C语言终极之链表
链表与数组的区别
链表就是一种存放数据的布局
数组是每一个元素的地点是一连的,链表是每个元素的地点是不一连的,需要接龙起来
数组不是那么的机动,但链表机动,更加适用于增删改查
数组的认识
- #include int main(){ int array[]={1,2,3,4}; int i; for(i=0;idata,t1.next->next->data); //第二个数:需要进入布局体指针所以要用 “->” ,再指向 data return 0;}
复制代码 步伐B
- #include struct test{ int data; struct test *next;};void printlink(struct test *head){ struct test *point =head; while(1){ if(point != NULL){ //不是空指针,打印数值,并指针向后偏移 printf("%d ",point->data); point = point->next; }else{ //指针为空,则跳出步伐 puchar('\n'); break; } }}int main(){ struct test t1 = {1,NULL}; struct test t2 = {2,NULL}; struct test t3 = {3,NULL}; t1.next = &t2; t2.next = &t3; printlink(&t1); //通过通报首元素的地点 return 0;}
复制代码
静态链表 盘算节点个数
- #include struct test{ int data; struct test *next;};void printlink(struct test *head){ struct test *point =head; while(1){ if(point != NULL){ //不是空指针,打印数值,并指针向后偏移 printf("%d ",point->data); point = point->next; }else{ //指针为空,则跳出步伐 putchar('\n'); break; } }}int node_Number(struct test *head){ int num = 0; struct test *point = head; while(point != NULL){ num++; //指针每偏移一次就+1 point = point -> next; } return num; //返回节点个数}int main(){ struct test t1 = {1,NULL}; struct test t2 = {2,NULL}; struct test t3 = {3,NULL}; t1.next = &t2; t2.next = &t3; printlink(&t1); //通过通报首元素的地点(打印链表) int ret = node_Number(&t1); //盘算链表个数 printf("链表的节点个数是%d\n",ret); return 0;}
复制代码
静态链表 查找节点
- #include struct test{ int data; struct test *next;};void printlink(struct test *head){ struct test *point =head; while(1){ if(point != NULL){ //不是空指针,打印数值,并指针向后偏移 printf("%d ",point->data); point = point->next; }else{ putchar('\n'); break; } }}int seek_node(struct test *head,int data){ struct test *point = head; while(point != NULL){ if(point -> data == data){ //链表节点的数值 便是 查找的数值 举行对比 return 1; } point = point -> next; } return 0;}int main(){ struct test t1 = {1,NULL}; struct test t2 = {2,NULL}; struct test t3 = {3,NULL}; t1.next = &t2; t2.next = &t3; printlink(&t1); //通过通报首元素的地点(打印链表) int ret = seek_node(&t1,2); //获取seek_node函数的返回值 if(ret == 1){ printf("链表中有 1\n"); }else{ printf("链表中没 1\n"); } ret = seek_node(&t1,8); if(ret == 1){ printf("链表中有 8\n"); }else{ printf("链表中没 8 \n"); } return 0;}
复制代码
静态链表从指定节点后方插入新节点
**思路
a.找到指定的节点
b.新节点地点 指向 指定节点的下一个节点地点
c.指定节点的下一个节点地点 指向 新节点 **
- #include struct test{ int data; struct test *next;};void printlink(struct test *head){ struct test *point =head; while(1){ if(point != NULL){ //不是空指针,打印数值,并指针向后偏移 printf("%d ",point->data); point = point->next; }else{ //指针为空,则跳出步伐 putchar('\n'); break; } }}int Insert_after_node(struct test *head,struct test *new,int data){ struct test *point = head; while(point != NULL){ if(point -> data == data){ // a.找到指定的节点 new ->next = point -> next; // b.新节点地点 指向 指定节点的下一个节点地点 point ->next = new; // c.指定节点的下一个节点地点 指向 新节点 return 1; } point = point ->next; } return 0;}int main(){ 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}; t1.next = &t2; t2.next = &t3; t3.next = &t4; t4.next = &t5; struct test new = {100,NULL}; printlink(&t1); //通过通报首元素的地点 int ret = Insert_after_node(&t1,&new,3); if(ret == 1){ //判定是否插入乐成 printf("插入乐成\n"); }else{ printf("插入失败\n"); } printlink(&t1); //通过通报首元素的地点 return 0;}
复制代码 静态链表从指定节点前方插入新节点
思路
A. 头节点插入
B.中间以及尾部插入
- #include struct test{ int data; struct test *next;};void printlink(struct test *head){ struct test *point =head; while(1){ if(point != NULL){ //不是空指针,打印数值,并指针向后偏移 printf("%d ",point->data); point = point->next; }else{ //指针为空,则跳出步伐 putchar('\n'); break; } }}struct test *Insert_front_node(struct test *head,struct test *new,int data){ struct test *point = head; if(point -> data == data){ //A. 头节点插入 new -> next = point; return new; //切记:返回的是新节颔首 } while(point -> next != NULL){ //B.中间以及尾部插入 if(point -> next -> data == data){ new ->next = point -> next; point ->next = new; return head; //切记:需要返回值原节点 } point = point ->next; } return head;}int main(){ 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}; t1.next = &t2; t2.next = &t3; t3.next = &t4; t4.next = &t5; struct test new = {100,NULL}; struct test *head = &t1; printlink(head); //通过通报首元素的地点 head= Insert_front_node(head,&new,1); //图一的效果 printlink(head); //通过通报首元素的地点 //head= Insert_front_node(head,&new,3); //图二的效果 //printlink(head); return 0;}
复制代码 图一:
图二:
静态链表删除指定节点
- #include struct test{ int data; struct test *next;};void printlink(struct test *head){ struct test *point =head; while(1){ if(point != NULL){ //不是空指针,打印数值,并指针向后偏移 printf("%d ",point->data); point = point->next; }else{ //指针为空,则跳出步伐 putchar('\n'); break; } }}struct test *delete_node(struct test *head,int data){ struct test *point = head; if(head -> data == data){ head = head -> next; return head; } while(point -> next != NULL){ if(point -> next -> data == data){ point -> next = point -> next -> next; return head; } point = point ->next; }}int main(){ 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}; t1.next = &t2; t2.next = &t3; t3.next = &t4; t4.next = &t5; struct test new = {100,NULL}; struct test *head = &t1; printf("原链表的节点:"); printlink(head); //通过通报首元素的地点 head = delete_node(head,1); //任意修改链表节点 printf("删除后的链表:"); printlink(head); //通过通报首元素的地点 return 0;}
复制代码
动态链表之头插法(步伐A与步伐B效果相同,但步伐B使用函数分装)
步伐A
- #include #include struct test{ int data; struct test *next;};void printlink(struct test *head){ struct test *point =head; while(1){ if(point != NULL){ //不是空指针,打印数值,并指针向后偏移 printf("%d ",point->data); point = point->next; }else{ //指针为空,则跳出步伐 putchar('\n'); break; } }}struct test *head_insert(struct test *head){ struct test *new; while(1){ new = (struct test *)malloc(sizeof(struct test)); printf("请输入新节点:"); scanf("%d",&(new->data)); if(new->data ==0){ printf("输入0,即将退出步伐\n"); return head; } if(head == NULL){ //刚创建链表时,链表为空 head = new; //所以将第一个数表现为链表头 }else{ //当链表中有数时 new -> next= head; //新节点的地点 指向 节颔首 head = new; //新节点为链表头 } } return head;}int main(){ struct test *head = NULL; head = head_insert(head); printlink(head); //通过通报首元素的地点}
复制代码 步伐B
- #include #include struct test{ int data; struct test *next;};void printlink(struct test *head){ struct test *point =head; while(1){ if(point != NULL){ //不是空指针,打印数值,并指针向后偏移 printf("%d ",point->data); point = point->next; }else{ //指针为空,则跳出步伐 putchar('\n'); break; } }}struct test *head_insert(struct test *head,struct test *new) //头插法{ if(head == NULL){ head = new; }else{ new -> next= head; head = new; } return head;}struct test *link_create(struct test *head) //创建链表{ struct test *new; while(1){ new = (struct test *)malloc(sizeof(struct test)); printf("请输入新节点:"); scanf("%d",&(new->data)); if(new->data ==0){ free(new); printf("输入0,即将退出步伐\n"); return head; } head = head_insert(head,new); }}int main(){ struct test *head = NULL; head = link_create(head); printlink(head); //通过通报首元素的地点}
复制代码
动态链表之尾插法
- include #include struct test{ int data; struct test *next;};void printlink(struct test *head){ struct test *point =head; while(1){ if(point != NULL){ //不是空指针,打印数值,并指针向后偏移 printf("%d ",point->data); point = point->next; }else{ //指针为空,则跳出步伐 putchar('\n'); break; } }}struct test *tail_insert(struct test *head,struct test *new) //尾插链表{ struct test *point =head; if(head == NULL){ //判定链表是否为空 head = new; //若为空,则将新节点 为 链表头 return head; } while(point -> next != NULL){ //判定链表的下一个是否为空 point = point -> next; //若不为空,直至走到链表节点的尾巴 } //退出循环 point -> next = new; //将新节点存储到链表尾巴 return head;}struct test *link_create(struct test *head){ struct test *new; while(1){ new = (struct test *)malloc(sizeof(struct test)); printf("请输入新节点:"); scanf("%d",&(new->data)); if(new->data ==0){ free(new); printf("输入0,即将退出步伐\n"); return head; } head = tail_insert(head,new); }}int main(){ struct test *head = NULL; head = link_create(head); printlink(head); //通过通报首元素的地点}
复制代码
来源:https://blog.csdn.net/weixin_47692173/article/details/111874866
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |