C语言描述:单向链表的相关操作

来源:互联网 发布:网络整合营销理论 原则 编辑:程序博客网 时间:2024/05/17 02:11
#include<stdio.h>#include<stdlib.h>typedef int ElemType;typedef struct LNode{ElemType data;//有效数据域 struct LNode *next;//下一个结点的地址 }LNode;typedef LNode* LinkList;//引用链表的参数是头指针,所以把结点型地址命名为LinkList //建立空表:为头结点分配内存,头结点的地址域为空 void InitList(LinkList *L){*L = (LNode*)malloc(sizeof(LNode));//为头结点分配内存,地址返回链表的头指针 if(*L==NULL)    exit(-1);//动态分配内存必须检测返回地址判断是否成功分配 (*L)->next = NULL;//头结点地址域为NULL }//销毁单向链表:free(头结点和表头到表尾的所有结点的地址)  void DestroyList(LinkList *L){LNode* p;while(*L){p = (*L)->next;free(*L);//free(p):释放p指向的内存,归还给操作做系统。*L = p;  //p变量仍存在,仍旧指向已经恢复自由的原先内存,一般还需要让p=NULL }}//清空单链表:free(表头和表尾的所有结点,保留头结点并使其地址域为NULL) void ClearList(LinkList *L){LNode*q,*p = (*L)->next;//指向表头,而不是头结点 while(p){q = p;free(p);p = q;}(*L)->next = NULL;}//判断单项链表是否为空 bool EmptyList(LinkList L){return L->next?false:true;}//返回单向链表的长度 int LengthList(LinkList L){LNode* p = L->next;int i = 0;//计数器 while(p)//数据流 {i++;p = p->next;}return i;}//得到链表某个位置的结点值 bool GetElem(LinkList L,int i,ElemType* e){//1<=i<=length if(i<1){printf("i的值不合理!\n");return false;}int j = 0;LNode* p = p->next;while(p&&j<i-1)//检测i是否>length {p = p->next;j++;}if(!p)//pls+1状态是每个循环结束后的最终状态值 {printf("i的值不合理!\n");return false;}*e = p->data;return true; }//在第i个位置前插入新结点:i<=i<=length+1 bool InsertList(LinkList L,int i,ElemType e){//寻找第i-1个结点,满足0<=i-1<=length,i的值自然合理 if(i-1<0){printf("i的值不合理!\n");return false;}LNode*p = L;//指向头结点 int j = 0;while(p&&j<i-1)//有两种理解方式:数据流,流下一个计数一次,流i-1次停止 {             //p切换指i-1次,直到p指向最后一个结点后停止p = p->next; j++;}if(!p){printf("i的值不合理!\n");return false;}//p指向第i-1个结点 LNode* q;q = (LNode*)malloc(sizeof(LNode));//构建要插入的新结点 q->data = e;q->next = p->next;//新节点保存第i个的地址 p->next = q;//第i-1个结点保存新结点的地址 return true; } //删除某个位置的结点:1<=i<=length bool DeleteList(LinkList L,int i,ElemType *e){//寻找第i-1个结点 0<=i<=length-1 if(i-1<0){printf("i的值不合理!\n");return false;}LNode* p = L;int j = 0;while(p&&j<i-1){p = p->next;j++;}if(!p||p->next==NULL)//pls+1或指向最后一个结点说明i值不合理 {printf("i的值不合理!\n");return false;}p->next = p->next->next;return true;}int LocateList(LinkList L,ElemType e){    int i = 1;LNode*p = L->next;while(p)//数据流 {if(p->data==e)return i;p = p->next;//满足切换下一个数据的要求,如果p=p->next->next,是跳跃切换 i++;}if(!p)return 0;}void TraverseList(LinkList L){LNode* p = L->next;while(p){printf("%d  ",p->data);p = p->next;}printf("\n");}// 输入n个元素的值,依次插在表头,建立带头结点结构的单向链表L  void CreateList(LinkList *L,int n)  {    int i;   LinkList p;   *L=(LinkList)malloc(sizeof(struct LNode));   (*L)->next=NULL; //为头结点分配内存    printf("请输入%d个数据\n",n);   for(i=n;i>0;--i)   {     p=(LinkList)malloc(sizeof(struct LNode));      scanf("%d",&p->data);      p->next=(*L)->next;      (*L)->next=p;   } }//输入n个元素的值,依次插在表尾,建立带表头结构的单链线性表  void CreateList2(LinkList *L,int n) {    int i;   LinkList p,q;   *L=(LinkList)malloc(sizeof(struct LNode)); // 生成头结点    (*L)->next=NULL;   q=*L;//q指向表尾    printf("请输入%d个数据\n",n);   for(i=1;i<=n;i++)   {     p=(LinkList)malloc(sizeof(struct LNode));     scanf("%d",&p->data);     q->next=p;     q=q->next;//q始终指向表尾    }   p->next=NULL; } //已知单向链表La和Lb的元素按值非递减排列。 //归并La和Lb得到新的单链线性表Lc,Lc的元素也按值非递减排列 void MergeList(LinkList La,LinkList *Lb,LinkList *Lc) {    LinkList pa=La->next,pb=(*Lb)->next,pc;   *Lc=pc=La;    while(pa&&pb)     if(pa->data<=pb->data)     {       pc->next=pa;       pc=pa;       pa=pa->next;     }     else     {       pc->next=pb;       pc=pb;       pb=pb->next;     }   pc->next=pa?pa:pb;    free(*Lb);    Lb=NULL; } /******************************************************************** int main()//测试MergeList {   int n=5;   LinkList La,Lb,Lc;   printf("按非递减顺序, ");   CreateList2(&La,n); // 正位序输入n个元素的值    printf("La=");    TraverseList(La);   printf("按非递增顺序, ");   CreateList(&Lb,n);    printf("Lb=");    TraverseList(Lb);   MergeList(La,&Lb,&Lc);    printf("Lc=");    TraverseList(Lc);   return 0; } ************************************************************/int main(){LinkList L;ElemType e;InitList(&L);int i;for(i=1;i<5;i++){InsertList(L,i,i);}printf("遍历单向链表\n");TraverseList(L);printf("在第5个位置插入11\n");InsertList(L,5,11);printf("遍历单向链表\n");TraverseList(L);printf("在第7个位置插入100\n");InsertList(L,7,100);printf("遍历单向链表\n");TraverseList(L);printf("删除第6个位置结点\n");DeleteList(L,6,&e);printf("遍历单向链表\n");TraverseList(L);printf("删除第0个位置结点\n");DeleteList(L,0,&e);printf("遍历单向链表\n");TraverseList(L);DeleteList(L,5,&e);printf("遍历单向链表\n");TraverseList(L);}

先找到课本,熟悉单向链表的结构;         关键词: 头结点,头指针,表头,表尾,数据域,地址域(指针域)
1,生成空表销毁链表               2,清空链表                 3,是否为空表               4,表长                  5,查找第i个结点的值
6,查找第一个等于e的结点在链表的位置                      7,插入                         8,删除                    9,遍历                             10,正序插入结点到单链表                               11,逆序插入结点到单链表                   12,将两个有序链表合并成一个有序链表
13,测试10,11,12的MAIN函数                  14,测试1-9的MAIN函数
练习题   (1)合并La,Lb,去掉重复结点
             (2)排序单向链表
#include<stdio.h>#include<stdlib.h>typedef int ElemType;typedef struct LNode{ElemType data;//有效数据域 struct LNode *next;//下一个结点的地址 }LNode;typedef LNode* LinkList;//引用链表的参数是头指针,所以把结点型地址命名为LinkList //建立空表:为头结点分配内存,头结点的地址域为空 void InitList(LinkList *L){*L = (LNode*)malloc(sizeof(LNode));//为头结点分配内存,地址返回链表的头指针 if(*L==NULL)    exit(-1);//动态分配内存必须检测返回地址判断是否成功分配 (*L)->next = NULL;//头结点地址域为NULL }//销毁单向链表:free(头结点和表头到表尾的所有结点的地址)  void DestroyList(LinkList *L){LNode* p;while(*L){p = (*L)->next;free(*L);//free(p):释放p指向的内存,归还给操作做系统。*L = p;  //p变量仍存在,仍旧指向已经恢复自由的原先内存,一般还需要让p=NULL }}//清空单链表:free(表头和表尾的所有结点,保留头结点并使其地址域为NULL) void ClearList(LinkList *L){LNode*q,*p = (*L)->next;//指向表头,而不是头结点 while(p){q = p;free(p);p = q;}(*L)->next = NULL;}//判断单项链表是否为空 bool EmptyList(LinkList L){return L->next?false:true;}//返回单向链表的长度 int LengthList(LinkList L){LNode* p = L->next;int i = 0;//计数器 while(p)//数据流 {i++;p = p->next;}return i;}//得到链表某个位置的结点值 bool GetElem(LinkList L,int i,ElemType* e){//1<=i<=length if(i<1){printf("i的值不合理!\n");return false;}int j = 0;LNode* p = p->next;while(p&&j<i-1)//检测i是否>length {p = p->next;j++;}if(!p)//pls+1状态是每个循环结束后的最终状态值 {printf("i的值不合理!\n");return false;}*e = p->data;return true; }//在第i个位置前插入新结点:i<=i<=length+1 bool InsertList(LinkList L,int i,ElemType e){//寻找第i-1个结点,满足0<=i-1<=length,i的值自然合理 if(i-1<0){printf("i的值不合理!\n");return false;}LNode*p = L;//指向头结点 int j = 0;while(p&&j<i-1)//有两种理解方式:数据流,流下一个计数一次,流i-1次停止 {             //p切换指i-1次,直到p指向最后一个结点后停止p = p->next; j++;}if(!p){printf("i的值不合理!\n");return false;}//p指向第i-1个结点 LNode* q;q = (LNode*)malloc(sizeof(LNode));//构建要插入的新结点 q->data = e;q->next = p->next;//新节点保存第i个的地址 p->next = q;//第i-1个结点保存新结点的地址 return true; } //删除某个位置的结点:1<=i<=length bool DeleteList(LinkList L,int i,ElemType *e){//寻找第i-1个结点 0<=i<=length-1 if(i-1<0){printf("i的值不合理!\n");return false;}LNode* p = L;int j = 0;while(p&&j<i-1){p = p->next;j++;}if(!p||p->next==NULL)//pls+1或指向最后一个结点说明i值不合理 {printf("i的值不合理!\n");return false;}p->next = p->next->next;return true;}int LocateList(LinkList L,ElemType e){    int i = 1;LNode*p = L->next;while(p)//数据流 {if(p->data==e)return i;p = p->next;//满足切换下一个数据的要求,如果p=p->next->next,是跳跃切换 i++;}if(!p)return 0;}void TraverseList(LinkList L){LNode* p = L->next;while(p){printf("%d  ",p->data);p = p->next;}printf("\n");}// 输入n个元素的值,依次插在表头,建立带头结点结构的单向链表L  void CreateList(LinkList *L,int n)  {    int i;   LinkList p;   *L=(LinkList)malloc(sizeof(struct LNode));   (*L)->next=NULL; //为头结点分配内存    printf("请输入%d个数据\n",n);   for(i=n;i>0;--i)   {     p=(LinkList)malloc(sizeof(struct LNode));      scanf("%d",&p->data);      p->next=(*L)->next;      (*L)->next=p;   } }//输入n个元素的值,依次插在表尾,建立带表头结构的单链线性表  void CreateList2(LinkList *L,int n) {    int i;   LinkList p,q;   *L=(LinkList)malloc(sizeof(struct LNode)); // 生成头结点    (*L)->next=NULL;   q=*L;//q指向表尾    printf("请输入%d个数据\n",n);   for(i=1;i<=n;i++)   {     p=(LinkList)malloc(sizeof(struct LNode));     scanf("%d",&p->data);     q->next=p;     q=q->next;//q始终指向表尾    }   p->next=NULL; } //已知单向链表La和Lb的元素按值非递减排列。 //归并La和Lb得到新的单链线性表Lc,Lc的元素也按值非递减排列 void MergeList(LinkList La,LinkList *Lb,LinkList *Lc) {    LinkList pa=La->next,pb=(*Lb)->next,pc;   *Lc=pc=La;    while(pa&&pb)     if(pa->data<=pb->data)     {       pc->next=pa;       pc=pa;       pa=pa->next;     }     else     {       pc->next=pb;       pc=pb;       pb=pb->next;     }   pc->next=pa?pa:pb;    free(*Lb);    Lb=NULL; } /******************************************************************** int main()//测试MergeList {   int n=5;   LinkList La,Lb,Lc;   printf("按非递减顺序, ");   CreateList2(&La,n); // 正位序输入n个元素的值    printf("La=");    TraverseList(La);   printf("按非递增顺序, ");   CreateList(&Lb,n);    printf("Lb=");    TraverseList(Lb);   MergeList(La,&Lb,&Lc);    printf("Lc=");    TraverseList(Lc);   return 0; } ************************************************************/int main(){LinkList L;ElemType e;InitList(&L);int i;for(i=1;i<5;i++){InsertList(L,i,i);}printf("遍历单向链表\n");TraverseList(L);printf("在第5个位置插入11\n");InsertList(L,5,11);printf("遍历单向链表\n");TraverseList(L);printf("在第7个位置插入100\n");InsertList(L,7,100);printf("遍历单向链表\n");TraverseList(L);printf("删除第6个位置结点\n");DeleteList(L,6,&e);printf("遍历单向链表\n");TraverseList(L);printf("删除第0个位置结点\n");DeleteList(L,0,&e);printf("遍历单向链表\n");TraverseList(L);DeleteList(L,5,&e);printf("遍历单向链表\n");TraverseList(L);}

0 0
原创粉丝点击