文章目录
- 链表的简易创建及输出数据
- 链表的遍历源码
- 链表的统计与查找
- 链表后插法
- 链表前插法之插链表头
- 链表前插法之插链表身
- 链表删除节点之删头
- 链表删除节点之删身
- 动态链表的头插法
- 链表动态头插法C语言源码的优化
- 链表动态尾插法C语言源码
链表的简易创建及输出数据
#include<stdio.h> struct test { int data; struct test *next; }; int main() { struct test t1={1,NULL}; struct test t2={2,NULL}; struct test t3={3,NULL}; t1.next = &t2; t2.next = &t3; printf("%d %d %d\n",t1.data,t1.next->data,t1.next->next->data); return 0; }
链表的遍历源码
#include<stdio.h> struct test//定义一个结构体 { int data;//定义数据 struct test *next;//定义结构体下一个 }; void printlink(struct test *head)//定义无类型输出(定义结构体指针头) { struct test *point;//定义结构体指向 point=head;//将头给指向 while(point !=NULL)//当指向不等于空 { printf("%d",point->data);//输出结构体指针指向的数据 point = point->next;//结构体指针指向数据的下一个给指向 } putchar('\n');//输出下一行 } int main() { int i;//定义i int array[]={1,2,3};//定义数组array并传参123 for(i=0;i<sizeof(array)/sizeof(array[0]);i++)//i=0;i小于12/3,i++ { printf(" 数组中的遍历%d ",array[i]);//输出 } putchar('\n'); struct test t1 ={1,NULL};//定义结构体节点t1,并传参1,NULL给t1 struct test t2 ={2,NULL};//同上 struct test t3 ={3,NULL}; struct test t4 ={4,NULL}; struct test t5 ={5,NULL}; struct test t6 ={6,NULL}; struct test t7 ={7,NULL}; t1.next =&t2;//将节点t1的下一个与t2地址相连,达到链接的目的 t2.next =&t3;//同上 t3.next =&t4; t4.next =&t5; t5.next =&t6; t6.next =&t7; printf("use t1 print three nums\n"); // printf("%d %d %d %d\n",t1.data,t1.next->data,t1.next->next->data,t1.next->next->next->data);//很土的方法输出 printlink(&t1);//调用printlink return 0; }
链表的统计与查找
#include<stdio.h> struct test { int data; struct test *next; }; void printlink(struct test *head)//定义输出函数 { struct test *point;//定义结构体指针变量 point=head;//将头给新的 (详细见上篇文章) while(point !=NULL) { printf("%d",point->data); point = point->next; } putchar('\n'); } int getlinktotalnodenum(struct test *head)//定义一个函数,计算链表节点个数 { int cnt = 0;//定义cnt并付出值0 while(head!=NULL)//当head不为空时 { cnt++;//+1 head = head->next;//当传参的值等于链表中的值 } return cnt;//返回cnt } int searchlink(struct test *head,int data)//查找链表中的值 { while(head !=NULL)///当头不为空时 { if(head->data==data)//如果头的数值等于传参的属实 { return 1;//返回1 } head=head->next;//遍历下一个 即将头的下一个给头 } return 0;//返回0 } int main() { int i; int array[]={1,2,3}; for(i=0;i<sizeof(array)/sizeof(array[0]);i++) { printf(" %d ",array[i]); } putchar('\n'); struct test t1 ={1,NULL}; struct test t2 ={2,NULL}; struct test t3 ={3,NULL}; struct test t4 ={4,NULL}; struct test t5 ={5,NULL}; struct test t6 ={6,NULL}; struct test t7 ={7,NULL}; t1.next =&t2; t2.next =&t3; t3.next =&t4; t4.next =&t5; t5.next =&t6; t6.next =&t7; printf("use t1 print three nums\n"); // printf("%d %d %d %d\n",t1.data,t1.next->data,t1.next->next->data,t1.next->next->next->data); printlink(&t1);//调用输出函数 int ret = getlinktotalnodenum(&t1);//调用函数,将返回值给ret printf("total num = %d\n",ret);//输出ret的值,即节点个数 ret = searchlink(&t1,1);//查找1并传参 if(ret == 0)//如果返回值为0 { printf("no 1\n");//输出表示没有 } else { printf("have 1\n");//除非就是有 } ret =searchlink(&t1,8);//查找8并传参 if(ret==0) { printf("no 8\n"); } else { printf("have 8\n"); } return 0; }
链表后插法
#include<stdio.h> struct test { int data; struct test *next; }; int insertfrombehind(struct test *head,int data,struct test *new)//定义函数后插法,并定义指针头,局部变量数据,新节点 { struct test *p =head;//定义指针p将头传给 while (p!=NULL)//当指针p不等于空时 { if(p->data == data)//如果指针的数据等于传参的数据 { new->next=p->next;//将原本指针p的下一个给新的下一个 也就是让新节点new的下一个指向原本老节点p的下一个 p->next=new;//将老节点p指向新节点new return 1;//返回1 } p=p->next;//遍历需要插入的节点,p的下一个给p,即后移 } return 0;//返回0,相当于没找到 } void printlink(struct test *head) { struct test *point; point=head; while(point !=NULL) { printf("%d",point->data); point = point->next; } putchar('\n'); } int getlinktotalnodenum(struct test *head) { int cnt = 0; struct test *p =head; while(p!=NULL) { cnt++; p = p->next; } return cnt; } int searchlink(struct test *head,int data) { while(head !=NULL) { if(head->data==data) { return 1; } head=head->next; } return 0; } int main() { int i; int array[]={1,2,3}; for(i=0;i<sizeof(array)/sizeof(array[0]);i++) { printf(" %d ",array[i]); } putchar('\n'); struct test t1 ={1,NULL}; struct test t2 ={2,NULL}; struct test t3 ={3,NULL}; struct test t4 ={4,NULL}; struct test t5 ={5,NULL}; struct test t6 ={6,NULL}; struct test t7 ={7,NULL}; t1.next =&t2; t2.next =&t3; t3.next =&t4; t4.next =&t5; t5.next =&t6; t6.next =&t7; struct test new = {100,NULL}; printf("use t1 print three nums\n"); // printf("%d %d %d %d\n",t1.data,t1.next->data,t1.next->next->data,t1.next->next->next->data); printlink(&t1); puts("after insert behind:\n");//打印在后面插入 insertfrombehind(&t1,3,&new);//调用后插函数,并传参3给函数,和新的节点 printlink(&t1);打印输出 /* int ret = getlinktotalnodenum(&t1); printf("total num = %d\n",ret); ret = searchlink(&t1,1); if(ret == 0) { printf("no 1\n"); } else { printf("have 1\n"); } ret =searchlink(&t1,8); if(ret==0) { printf("no 8\n"); } else { printf("have 8\n"); } */ return 0; }
链表前插法之插链表头
#include <stdio.h> struct test { int data; struct test *next; }; struct test* insertfromfor(struct test *head,int data,struct test *new)//定义结构体函数前插法插头 { struct test *p =head;//定义局部结构体指针变量p,并将头给p if(p->data==data)//如果插入的地方是正好是传参的值 { new->next=head;//将新节点的下一个链接当前的上头 return new;//将新节点返回 } } void printlink(struct test *head)//遍历打印输出 { struct test *point; point=head; while(point !=NULL) { printf("%d ",point->data); point = point->next; } putchar('\n'); } int main() { struct test *head = NULL;//定义结构体指针头,并传参空 putchar('\n'); struct test t1 ={1,NULL}; struct test t2 ={2,NULL}; struct test t3 ={3,NULL}; struct test t4 ={4,NULL}; struct test t5 ={5,NULL}; struct test t6 ={6,NULL}; struct test t7 ={7,NULL}; t1.next =&t2; t2.next =&t3; t3.next =&t4; t4.next =&t5; t5.next =&t6; t6.next =&t7; head =&t1;//将t1地址给头 struct test new2 ={101,NULL};//定义一个新节点,并传实参 head=insertfromfor(head,1,&new2);//调用插头函数,并赋值把返回值给头 puts("after insert head:\n"); printlink(head);//输出打印 system("pause"); return 0; }
链表前插法之插链表身
#include <stdio.h> struct test { int data; struct test *next; }; struct test* insertfromfor(struct test *head,int data,struct test *new)//定义头插法 { struct test *p =head;//定义结构体指针p,并传参形参head if(p->data==data)//如果p的数据和形参中的数值相等 { new->next=head;//将新的节点的下一个给头(头插法之插头) return new;//返回新节点 } while(p->next !=NULL)//当指针p不为空时 { if(p->next->data==data)//如果p的下一个的数据等于形参中的数据 { new->next=p->next;//新节点的下一个给原p指针节点的下一个 p->next=new;p节点的下一个给新节点 printf("insert ok\n");//输出 return head; } p=p->next;//如果没找到下一个,就执行下一个遍历到下一个,直到if语句成立 } printf("no this data %d\n",data);//说明wille语句中没找到传参的值,输出 return head; } void printlink(struct test *head) { struct test *point; point=head; while(point !=NULL) { printf("%d ",point->data); point = point->next; } putchar('\n'); } int main() { struct test *head = NULL; putchar('\n'); struct test t1 ={1,NULL}; struct test t2 ={2,NULL}; struct test t3 ={3,NULL}; struct test t4 ={4,NULL}; struct test t5 ={5,NULL}; struct test t6 ={6,NULL}; struct test t7 ={7,NULL}; t1.next =&t2; t2.next =&t3; t3.next =&t4; t4.next =&t5; t5.next =&t6; t6.next =&t7; head =&t1; struct test new3 ={103,NULL}; head=insertfromfor(head,4,&new3); puts("在4前面插个新数:\n");//在4前面插入103 printlink(head);//调用输出函数 system("pause"); return 0; }
链表删除节点之删头
#include <stdio.h> #include <stdlib.h> struct test { int data; struct test *next; }; void printlink(struct test *head) { struct test *point; point=head; while(point !=NULL) { printf("%d ",point->data); point = point->next; } putchar('\n'); } struct test* deletnode(struct test *head , int data)//定义结构体变量删除节点 { struct test *p =head;//将形参头给指针变量p if(p->data==data)//如果p的数据与形参中的数据相同 { head =head->next;//头的下一个给头,也就是下一个成头了 free(p);//将原先头的地址空间释放 return head;//返回头 } } int main() { struct test *head = NULL; // struct test t1 ={1,NULL}; struct test *p = (struct test*)malloc (sizeof(struct test));//开辟指针变量p 的空间并强转成结构体struct test *型 struct test t2 ={2,NULL}; struct test t3 ={3,NULL}; struct test t4 ={4,NULL}; struct test t5 ={5,NULL}; struct test t6 ={6,NULL}; struct test t7 ={7,NULL}; p->data =1;//给头赋值1 // t1.next =&t2; p->next =&t2;//将p的下一个与t2的地址链接 t2.next =&t3; t3.next =&t4; t4.next =&t5; t5.next =&t6; t6.next =&t7; // head =&t1; head =p; //指针p是头 printlink(head);//删除前输出一遍 head = deletnode(head ,1);//删除第一个后 printlink(head);//输出 system("pause"); return 0; }
链表删除节点之删身
#include <stdio.h> #include <stdlib.h> struct test { int data; struct test *next; }; void printlink(struct test *head) { struct test *point; point=head; while(point !=NULL) { printf("%d ",point->data); point = point->next; } putchar('\n'); } struct test* deletnode(struct test *head , int data) { struct test *p =head; if(p->data==data) { head =head->next; free(p); return head; } while(p->next !=NULL)//当指针P的下一个不为空时 { if(p->next->data==data)//如果p 的下一的数据等于形参的数据 { //struct test *tmp =p;//动态创建时需要用到 p->next =p->next->next;//将p的下一个的下一个等于P的下一个,也就是把P的下一个删除了直接连接到后面那一个了 //free(tmp);//释放内存空间 return head; } p=p->next; } return head; } int main() { struct test *head = NULL; // struct test t1 ={1,NULL}; struct test *p = (struct test*)malloc (sizeof(struct test)); struct test t2 ={2,NULL}; struct test t3 ={3,NULL}; struct test t4 ={4,NULL}; struct test t5 ={5,NULL}; struct test t6 ={6,NULL}; struct test t7 ={7,NULL}; p->data =1; // t1.next =&t2; p->next =&t2; t2.next =&t3; t3.next =&t4; t4.next =&t5; t5.next =&t6; t6.next =&t7; // head =&t1; head =p; printlink(head); head = deletnode(head ,3);//传参删除数据3这个节点 printlink(head); return 0; }
动态链表的头插法
#include <stdio.h> #include <stdlib.h> struct test { int data; struct test *next; }; void printlink(struct test *head) { struct test *point; point=head; while(point !=NULL) { printf("%d ",point->data); point = point->next; } putchar('\n'); } struct test* insertfromhead(struct test *head) //动态头插法 { struct test *new;//定义一个新的节点 while(1) { new =(struct test *)malloc(sizeof(struct test));//开辟结构体空间 printf("input your new node data:\n");//输出 scanf("%d",&(new->data));//输入,传给新节点指针变量的地址 if(new->data ==0)//如果输入的是0 { printf("0 quit\n");//输出0 return head;//返回 退出 } if(head==NULL)//如果为空 { head=new;将新的给头,也就是,一开始什么也没有,也就是第一个 } else { new->next=head;//将新的下一个与头连接 head=new;//将新的给头,也就是进来后新的就成了头 } } return head;//返回 } int main() { struct test *head = NULL;//定义头为空 head = insertfromhead(head);//调用函数,并给头 printlink(head);//输出 return 0; }
链表动态头插法C语言源码的优化
#include <stdio.h> #include <stdlib.h> struct test { int data; struct test *next; }; void printlink(struct test *head) { struct test *point; point=head; while(point !=NULL) { printf("%d ",point->data); point = point->next; } putchar('\n'); } struct test* insertfromhead(struct test *head,struct test *new)//定义结构体指针变量头插法 { if(head==NULL)//如果头进来为空 { head=new;//那么将新的节点给头 } else//如果不是 { new->next=head;//将新节点的下一个给头,也就是与之前的头连接 head=new;//并将新节点给头,也就是新的成了头了 } return head; } struct test* createlink(struct test *head)//定义结构体调用函数 { struct test *new; while(1) { new =(struct test *)malloc(sizeof(struct test));//开辟新的空间 printf("input your new node data:\n");//输出打印新的节点的数据 scanf("%d",&(new->data));//输入,传给新的数据 if(new->data ==0)//如果输入的新的数据为0 { printf("0 quit\n");//输出0 free(new);//释放内存空间 return head;返回头 } head = insertfromhead(head,new);//调用头插法函数并将返回数据给头 } } int main() { struct test *head = NULL;//定义结构体指针头变量为空 head = createlink(head);//调用函数 printlink(head);//调用输出函数 struct test t1 ={1000,NULL};//定义结构体t1,并传参 head = insertfromhead(head,&t1);//调用头插法函数并传参给头 printlink(head);//调用输出 return 0; }
链表动态尾插法C语言源码
#include <stdio.h> #include <stdlib.h> struct test { int data; struct test *next; }; void printlink(struct test *head) { struct test *point; point=head; while(point !=NULL) { printf("%d ",point->data); point = point->next; } putchar('\n'); } struct test* insertbehind (struct test *head,struct test *new) { struct test *p =head; if(p==NULL) { head=new;//将新的给头 return head; } while(p->next != NULL) { p=p->next;//将原节点下一个给原节点 } p->next =new;//将新的给原节点的下一个,也就是在原来的后面加上个新的 return head; } struct test* createlink2(struct test *head)//动态后插法 { struct test *new; while(1) { new =(struct test *)malloc(sizeof(struct test)); printf("input your new node data:\n"); scanf("%d",&(new->data)); if(new->data ==0) { printf("0 quit\n"); free(new); return head; } head = insertbehind(head,new); } } int main() { struct test *head = NULL; head = createlink2(head); printlink(head); struct test t2 ={2000,NULL}; head =insertbehind(head,&t2); printlink(head); return 0; }