线性表基本操作
来源:互联网 发布:数组和链表有什么区别 编辑:程序博客网 时间:2024/05/18 13:09
线性表是最简单、也是最基本的一种线性数据结构。它有两种存储方法:顺序表和链表,它一般有12种基本操作,主要基本操作是插入、删除和查找等。我这里把顺序表和单链表的这12种操作按自己的理解写了一遍,两两对照着看应该要好一点。
线性表12基本操作
准备(接下来也是这样比较,不做说明了)
顺序表(Sq —— SequenceList):
#define LIST_INIT_SIZE 100#define LISTINCREMENT 10typedef char ElemType; //注意!typedef struct{ ElemType *elem; //用一维数组存储数据元素 int length; //线性表当前的长度 int listsize; //当前分配的数组空间的最大容量(以ElemType为单位) int incrementsize;//约定的增补空间量(以ElemType为单位)}SqList;void ErrorMassage(char *s) //输出字符串s并退出原函数{ cout<<s<<endl; exit(1);}/*做函数参数时&e与*e的区别:前者称为引用,使用被引用者的内存,本身无内存,相当于直接使用被引用者; 而后者是指针,指向一段内存且本身也有内存*///(SqList &L)需要对顺序表内容进行改变时加&,否则不加void ListIncrement(SqList &L) //为顺序表扩大L.incrementsize个元素空间{ realloc(L.elem,(L.listsize+L.incrementsize)*sizeof(ElemType)); L.listsize+=L.incrementsize; return;}
单链表(L —— LinkList):
特别说明:我创建的单链表是有一个空的头结点,并不是直接取第一个结点做头结点,这点与本科书上的不相同
typedef char ElemType;typedef struct LNode{ ElemType data; struct LNode *next;}LNode,*LinkList;void ErrorMassage(char *s) //输出字符串s并退出原函数{ cout<<s<<endl; exit(1);}
一、InitList(&L):构造一个空的顺序表L
void InitList_Sq(SqList &L) //创建一个空的顺序表L,但是已经分配了内存{ L.elem=new ElemType[LIST_INIT_SIZE]; L.length=0; L.listsize=LIST_INIT_SIZE; L.incrementsize=LISTINCREMENT; return;}
void InitList_L(LinkList &L,int n) //创建一个有头结点的单链表{ LNode *p,*q; L=new LNode; for(int i=0;i<n;i++) { q=new LNode; q->data='A'+i; //->是指针操作符 if(i>0) p->next=q; else L->next=q; p=q; } q->next=NULL; //令尾结点z指向空,以此作为某些函数结束条件 return;}
二、ListInsert(&L,i,e):在第i个元素前插入新元素e
void ListInsert_Sq(SqList &L,int i,ElemType e) //将元素e插入到顺序表第i个位置之前{ if(i<1||i>L.length+1) ErrorMassage("i is invalid!"); if(L.length>=L.listsize) ListIncrement(L); ElemType *p,*q; p=&L.elem[i-1]; for(q=&L.elem[L.length-1];q>=p;q--) *(q+1)=*q; *p=e; L.length++; //插入一个元素后L长度加1 return;}
void ListInsert_L(LinkList &L,LNode *q,LNode *s) //在q前插入新结点s{ LNode *p=L; for(;p->next!=q&&p->next;p=p->next); s->next=p->next; p->next=s; return;}
三、ListDelete(&L,i,&e):删除第i个元素,存入e中
void ListDelete_Sq(SqList &L,int i,ElemType &e) //删除L的第i个元素,并用e返回其值{ if(i<1||i>L.length) ErrorMassage("i is invalid!"); ElemType *q; e=L.elem[i-1]; for(q=&L.elem[i-1];q<=&L.elem[L.length-1];q++) *q=*(q+1); L.length--; //删除一个元素后L长度减1 return;}
void ListDelete_L(LinkList &L,LNode *q,ElemType &e) //删除L中的q结点,并用e返回其内元素值{ LNode *p; p=L; for(;p->next!=q&&p->next;p=p->next); p->next=p->next->next; e=q->data; delete q; return;}
四、LocateElem(L,e):返回第1个与e相等元素的位序
int LocateElem_Sq(SqList L,ElemType e) //返回L中第1个与e相等的元素的位序,没有则返回0{ int i; for(i=0;i<L.length;i++) if(L.elem[i]==e) return i+1; if(i==L.length) return 0;}
int LocateElem_L(LinkList L,ElemType e) //返回L中第1个与e相等元素的位序,若不存在返回0{ LNode *p; int i; p=L->next; for(i=1;p;i++,p=p->next) if(p->data==e) return i; return 0;}
五、GetElem(L,i,&e):用e返回第i个元素的值
void GetElem_Sq(SqList L,int i,ElemType &e) //用e返回L中第i个元素的值{ if(i<1||i>L.length) ErrorMassage("i is invalid!"); e=L.elem[i-1]; return;}
void GetElem_L(LinkList L,int i,ElemType &e) //用e返回L中第i个结点中元素的值{ if(i<1||i>ListLength_L(L)) ErrorMassage("i is invalid!"); LNode *p; p=L->next; for(int j=1;j!=i&&p;p=p->next,j++); e=p->data; return;}
六、DestroyList(&L):销毁线性表L
void DestroyList_Sq(SqList &L) //销毁顺序表{ delete []L.elem; L.length=0; //顺序表销毁后长度为0,数组空间为0 L.listsize=0; return;}
void DestroyList_L(LinkList &L) //销毁链表{ LNode *p,*q; q=L->next; while(q) { p=q->next; delete q; q=p; } delete L; return;}
七、ListLength(L):返回L中元素个数
int ListLength_Sq(SqList L) //返回顺序表L的当前长度{ return L.length;}
int ListLength_L(LinkList L) //返回L所指链表的长度{ LNode *q; int l=0; q=L->next; while(q) { l++; q=q->next; } return l;}
八、ListTraverse(L):依次输出L中每个元素
void ListTraverse_Sq(SqList L) //依次输出L中的每个元素{ int i=0; if(L.length<=0) return; for(i=0;i<L.length-1;i++) cout<<L.elem[i]<<" "; cout<<L.elem[i]<<endl; return;}
void ListTraverse_L(LinkList L) //依次输出链表中的元素{ LNode *q; q=L->next; while(q) { cout<<q->data<<" "; q=q->next; } cout<<endl; return;}
九、ClearList(&L):将L重置为空表
void ClearList_Sq(SqList &L) //将L置为空表{ for(int i=0;i<L.length;i++) L.elem[i]='\0'; L.length=0; //置为空表后长度为0 return;}
void ClearList_L(LinkList &L) //将L置为空表,即只留下头结点{ DestroyList_L(L->next); L->next=NULL; return;}
十、LIstEmpty(L):若L为空表返回True,否则返回False
bool ListEmpty_Sq(SqList L) //判断L是否为空表,若是返回true,否则返回false{ if(L.length==0) return true; else return false;}
bool ListEmpty_L(LinkList L) //判断L是否为空表,除头结点以外{ int i; LNode *p; p=L->next; for(i=0;p;p=p->next,i++); if(i) return false; else return true;}
十一、PriorElem(L,cur_e,&pre_e):用pre_e返回cur_e的前驱
ElemType PriorElem_Sq(SqList L,ElemType e) //返回e的前驱元素,若e是第一个或者不是L中元素则输出提示信息{ int i=LocateElem_Sq(L,e); if(i<=1) ErrorMassage("No priorelem!"); else return L.elem[i-2];}
LNode* PriorElem_L(LinkList L,ElemType cur_e) //返回cur_e的前驱结点,没有则输出提示信息{ LNode *p; p=L->next; if(LocateElem_L(L,cur_e)<=1) //若cur_e不是L中元素或者e是L中第一个元素 ErrorMassage("No priornode!"); while(p->next->data!=cur_e) p=p->next; return p;}
十二、NextElem(L,cur_e,&next_e):返回后继
ElemType NextElem_Sq(SqList L,ElemType e) //返回e的后继元素,若e是最后一个或者不是L中元素则输出提示信息{ int i=LocateElem_Sq(L,e); if(i==0||i==L.length) ErrorMassage("No nextelem!"); else return L.elem[i];}
LNode* NextElem_L(LinkList L,ElemType cur_e) //返回cur_e的后继结点,没有则输出提示信息{ LNode *p; p=L->next; int i=LocateElem_L(L,cur_e); if(i<1||i>=ListLength_L(L)) //若cur_e不是L中元素或者是最后一个 ErrorMassage("No nextelem!"); for(;p->data!=cur_e;p=p->next); return p->next;}
0 0
- 线性表基本操作
- 线性表基本操作
- 线性表基本操作
- 线性表基本操作
- 线性表基本操作
- 线性表的基本操作
- 线性表的基本操作
- 线性表的基本操作
- 线性表的基本操作
- 线性表的基本操作
- 线性表的基本操作
- 【数据结构】线性表基本操作
- 线性表的基本操作
- 线性表的基本操作
- 线性表的基本操作
- 线性表的基本操作
- 线性表的基本操作
- 线性表的基本操作
- FFmpeg学习6:视音频同步
- win环境下mysql 5.7.15 x64变量默认值
- 视频相关术语的介绍
- caffe中的normalization实现
- 今天在学习bootstrap,在使用字体图标的时候,无法显示
- 线性表基本操作
- 微信小程序开发资源 Awesome 大搜集
- Swift - 使用NSDataDetector进行URL验证,及提取字符串中所有链接
- 让 Terminal/Vim 使用 solarized风格
- DIV+CSS布局实战---海南旅游网
- SQLSERVER 文件组解决大数据量数据存储
- 自定义属性步骤
- EL,JSTL页面识别问题
- mysql性能分析