链表的实现

    科技2025-07-21  5

    #include <bits/stdc++.h> #define OK 1 #define ERROR 0 using namespace std; typedef int ElemType; typedef int Status; typedef struct LNode{ ElemType data; struct LNode *next; }Lnode,*LinkList; //初始化 Status InitList(LinkList &L){ L=(LinkList)malloc(sizeof(LNode)); if(!L){ exit(OVERFLOW);} L->next=NULL; return OK; } /*单链表的读取 读取链表的第i个位置的元素,由e返回其值 1. 声明一个结点 p 指向链表第一个结点,初始化 j 从 1 开始; 2. 当 j<i 时,就遍历链裴,让 p 的指针向后移动,不断指向下一结点, j 累加 1; 3. 若到链表末尾 p 为空,则说明第 i 个元素不存在; 4. 否则查找成功,返回结点 p 的数据。 */ Status GetElem(LinkList L,int i,ElemType &e){ LinkList p=L->next;//p指向首元结点 int j=1;//j用于计数 while(j<i&&p){ p=p->next; j++; } if(!p||j>i) return ERROR;//健壮性 e=p->data; return OK; } /*插入算法: L的第i个位置之前插入元素e 1. 声明一结点 p 指向链表头结点,初始化 j 从 0 开始; 2. 当 j<i-1 时,就遍历链表,让 p 的指针向后移动,不断指向下一结点, j 累加 1; 3. 若到链表末尾 p为空,则说明第 i 元素不存在; 4. 否则查找成功,在系统中生成一个空结点 s; 5. 将数据元素 e 赋值给 s->data ; 6. 单链表的插入标准语旬 s->next=p->next;p->next=s; 7. 返回成功。 */ Status ListInsert(LinkList &L,int i,ElemType e){ LinkList p=L,s; int j=0; while(j<i-1&&p){ j++; p=p->next; } if(j>i-1||!p){ return ERROR; } s=(LinkList)malloc(sizeof(LNode));//建立一个新节点 s->data=e;//赋值 //插入过程 s->next=p->next; p->next=s; return OK; } /*删除算法 删除L的第i个元素,并由e返回其值 1. 声明一结点 p 指向链表第一个结点,初始化j从0开始 2. 当 j<i-1同时,就遍历链表,让p的指针向后移动,不断指向下一个结点,j累加1 3. 若到链表末尾 p为空,则说明第i个元素不存在; 4. 否则查找成功,将欲删除的结点 p->next 赋值给 q; S. 单链表的删除标准语句 p->next=q->next; 6. 将 q 结点中的数据赋值给 e, 作为返回; 7. 释放 q 结点; 8. 返回成功。*/ Status ListDelete(LinkList &L,int i,ElemType e){ LinkList p=L; int j=0; while(j<i-1&&p->next){ p=p->next; j++; } if(j>i-1||(!p->next)){ return ERROR; } LinkList q; q=p->next;p->next=q->next;//删除结点 e=q->data; free(q);//释放结点空间 return OK; } /*按值查找 按值查找是在链表中,查找是否有结点值等于给定值key的结点, 若有的话,则返回首次找到的其值为key的结点的存储位置; 否则返回NULL。*/ Status LinkSearch(LinkList L,ElemType key,LNode *e){ LinkList p=L; while(p->next&&p->next->data!=key){ p=p->next; } if(!p->next)return ERROR; e=p->next; return OK; } //前驱 Status LinkPiror(LinkList L,ElemType cur_e,ElemType &e){ LinkList p=L->next; while(p->next){//p有后继 if(p->next->data==cur_e){//p的后继 e=p->data; return OK; } p=p->next; } return ERROR; } //后继 Status LinkNext(LinkList L,ElemType cur_e,ElemType &e){ LinkList p=L->next; while(p->next){ if(p->data==cur_e){ e=p->next->data; return OK; } p=p->next; } return ERROR; } /*销毁 1. 声明一个节点q 2. 让q等于L的下一个地址 3. 释放L,循环,直到表为空*/ void DestroyList(LinkList &L){ LinkList q; while(L){ q=L->next; free(L); L=q; } } /*清空 让头结点指针域为空*/ void ClearList(LinkList L){ LinkList p=L->next; L->next=NULL; DestroyList(p); } //判空 void ListEmpty(LinkList L){ int k; if(L->next==NULL)k=1; else k=0; if(k==1) printf("表为空\n") ; else printf("表不为空\n"); } //求长(求元素个数) int ListLength(LinkList L){ int i=0; LinkList p=L->next; while(p){ i++; p=p->next; } return i; } /*创建链表(头插法) 1. 声明一结点 p 和计数器变量 i 2. 初始化一空链表 L 3. 让 L 的头结点的指针指向 NULL,即建立一个带头结点的单链表 4. 循环: 1生成一新结点赋值给 p; 2将待插入的数字赋值给p的数据域 p->data; 3将p插入到头结点与前一新结点之间。*/ void CreateListHead(LinkList &L,int n){ //建立带头结点的链表L,逆位序输入n个元素值 LinkList p; int i; InitList(L); for(i=0;i<n;i++){ p=(LinkList)malloc(sizeof(LNode));//建立新节点 cin>>p->data; p->next=L->next;L->next=p;//插表头 } } //创建链表(尾插法) void CreateListTail(LinkList &L,int n){ //建立带头结点的链表L,逆位序输入n个元素值 LinkList p,r; int i; InitList(L); r=L; for(i=0;i<n;i++){ p=(LinkList)malloc(sizeof(LNode));//建立新节点 cin>>p->data; r->next=p;//将表尾终端节点的指针指向新结点 r=r->next;// 将当前的新节点定义为农表位终端节点 } p->next=NULL;//表示当前列表结束 } //遍历 void show(LinkList L){ LinkList p=L->next; while(p!=NULL){ printf("%d ",p->data); p=p->next; } cout<<endl; } int main() { LinkList L; ElemType e,e0; int i,j,k; InitList (L);//初始化 cout<<"请输入待插入链表的5个数"<<endl; CreateListHead(L,5);//头插法 show(L); ListEmpty(L);//判空 printf("%d\n",ListLength(L));//求长度 ClearList(L);//清空 ListEmpty(L);//判空 printf("%d\n",ListLength(L));//求长度 DestroyList(L); cout<<"请输入待插入链表的5个数"<<endl; CreateListTail(L,5);//尾插法 show(L); ListInsert(L,2,9); show(L); ClearList(L);//清空 for(j=1;j<=10;j++){ ListInsert(L,1,j);//表尾插入 } show(L); //前驱,测试头两个元素 for(j=1;j<=2;j++){ GetElem(L,j,e0); i=LinkPiror(L,e0,e); if(i==ERROR)printf("元素%d无前驱\n",e0); else printf("元素%d的前驱为%d\n",e0,e); } //后继,测试后两个元素 for(j=ListLength(L)-1;j<=ListLength(L);j++){ GetElem(L,j,e0); i=LinkNext(L,e0,e); if(i==ERROR)printf("元素%d无后继\n",e0); else printf("元素%d的后继为%d\n",e0,e); } //删除 i=ListDelete(L,5,e); if(i==ERROR)printf("删除第5个元素失败\n"); else printf("删除第5个元素成功,其值为%d\n",e); i=ListDelete(L,12,e); if(i==ERROR)printf("删除第12个元素失败\n"); else printf("删除第12个元素成功,其值为%d\n",e); DestroyList(L);//销毁L printf("销毁L后,L=%u\n",L); return 0; }

    结果:

    请输入待插入链表的5个数 1 2 3 4 5 5 4 3 2 1 表不为空 5 表为空 0 请输入待插入链表的5个数 5 4 3 2 1 5 4 3 2 1 5 9 4 3 2 1 10 9 8 7 6 5 4 3 2 1 元素10无前驱 元素9的前驱为10 元素2的后继为1 元素1无后继 删除第5个元素成功,其值为1 删除第12个元素失败 销毁L后,L=0
    Processed: 0.012, SQL: 8