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
- C语言描述:单向链表的相关操作
- C语言中单向链表的相关操作
- 数据结构——单向链表的基本操作C语言描述(克服对头结点和尾结点的操作)
- 最基本的单向链表操作 C语言
- C语言单向链表的操作(持续更新中)
- 使用C语言对单向链表的操作
- 单向链表的C语言实现与基本操作
- 有序单向链表的相关操作
- 单向链表的相关操作
- 单向链表相关操作
- 单向链表相关操作
- C语言单向链表的实现
- 求助 C语言的单向链表
- C语言实现的单向链表
- 单向链表的C语言实现
- c语言的单向链表
- C语言单向链表的建立
- C语言单向链表的实现
- sping学习笔记
- ConstraintLayout 的使用
- Vim Editor Assistant
- 117:Search for a Range
- 主动信息收集之端口扫描的一些脚本
- C语言描述:单向链表的相关操作
- MySQL设置主键外键时错误:ERROR 1064 (42000)
- 字符串相关Tips
- LeetCode Week5:Recover Binary Search Tree、Binary Tree Maximum Path Sum
- 人脸识别数据库
- 安装ofsoftswitch13
- 棋盘问题
- Spark学习之RDD常用操作
- web兼容性问题