当前位置: 首页 > news >正文

链表头插法的优化补充、尾插法完结!

头插法的优化补充

这边我们将考虑到可以将动态创建链表,和插入新链表到链表头前方,成为新链表头的方法分开,使其自由度上升,在创建完链表后,还可以添加链表元素到成为新的链表头。

就是说可以单独的调用这个insertHeadBefore这个函数

Tips:

不管尾插法还是头插法都有这段代码,因为如果链表都是空的那肯定要先将new的做头了

尾插法(动态创建)

Tips:指针只是一个辅助指针,用于在链表中移动,最终会指向链表的最后一个节点。

还有头插法和尾插法的共同应用

直接上代码

#include <stdio.h>

#include <stdlib.h>

struct Test

{

    int data;

    struct Test *next;

};

struct Test *insertHeadBefore(struct Test *head,struct Test *new)

{

if(head == NULL){

head = new;

new->next=NULL;

}else{

new->next=head;

head = new;

}

return head;

}

struct Test *insertTailLater(struct Test *head,struct Test *new)

{

struct Test *p;

p = head;

if(p == NULL){ // 链表为空时,直接返回 new 作为新的头节点

 head = new;

 new->next=NULL;

 return head;

}

while(p->next != NULL){

  p=p->next;

 }

 p->next=new;

 new->next=NULL;//比如我输入1、2,在2的时候,那么一定要让new->next初始化为NULL不然不能表示链表的状态

                //因为你输入new->next=NULL;后链表此时才会变成1->2 表示结尾,也是下一个数字插入的前提

 return head;

}

struct Test * createLink1(struct Test *head)

{

struct Test *new;

while(1){

new = (struct Test *)malloc(sizeof(struct Test));

if(new==NULL){

printf("内存分配失败");

return head;

}

printf("请输入data (输入0退出)\n");

scanf("%d",&(new->data));

if(new->data == 0){

printf("quit\n");

free(new);

return head;

}

head = insertHeadBefore(head,new);

}

return head;

}

struct Test * createLink2(struct Test *head)

{

struct Test *new;

while(1){

new = (struct Test *)malloc(sizeof(struct Test));

if(new==NULL){

printf("内存分配失败");

return head;

}

printf("请输入data (输入0退出)\n");

scanf("%d",&(new->data));

if(new->data == 0){

printf("quit\n");

free(new);

return head;

}

head = insertTailLater(head,new);

}

return head;

}

void printfInfo(struct Test *head)

{

    struct Test *point = head;

    while(point != NULL){

        printf("%d ", point->data);

        point = point->next;

    }

    putchar('\n');

}

int main()

{

    struct Test *head = NULL;

    head = createLink2(head);

    printfInfo(head);

struct Test new1 ={1000,NULL};

head = insertHeadBefore(head,&new1);

printfInfo(head);

struct Test new2 ={2000,NULL};

head = insertTailLater(head,&new2);

printfInfo(head);

    return 0;

}

认真的问问自己,理解了吗?

这个链表的原理真的要好好理解!!!很重要

Tips:将新节点的 next 指针设置为 NULL 并不仅仅是表示本次插入操作的结束,而是维护链表结构完整性和表示链表结尾的必要操作。下面详细解释这个操作的意义以及与后续输入的关系:

        表示链表结束:在单链表结构中,最后一个节点的 next 指针需要设置为 NULL,这是单链表表示结尾的约定。当输入 2 并插入到链表中时,1 节点是原来的最后一个节点,2 是新插入的节点。将 2 节点的 next 指针设置为 NULL,就明确表示 2 是当前链表的最后一个节点,这样在后续遍历链表(例如调用 printfInfo 函数)时,程序可以根据 next 指针是否为 NULL 来判断是否到达链表结尾。

        为后续插入做准备:将新节点的 next 指针设置为 NULL 并不意味着链表不再变化。当继续输入 3 时,程序会再次执行 createLink2 函数中的逻辑,为 3 分配新节点,读取输入值 3,然后再次调用 insertTailLater 函数。此时链表状态为 1 -> 2insertTailLater 函数会遍历链表找到当前的尾节点(即数据为 2 的节点),然后将新节点(数据为 3 的节点)连接到尾节点之后,并将新节点的 next 指针设置为 NULL,链表状态变为 1 -> 2 -> 3

        数据结构的一致性:在链表操作中,保持每个节点的 next 指针正确指向是非常重要的。将最后一个节点的 next 指针设置为 NULL 确保了链表结构的一致性,使得链表的操作(如插入、遍历等)能够正确执行。如果不将新插入的节点的 next 指针设置为 NULL,在后续操作中可能会导致链表遍历错误,因为程序无法正确判断链表的结尾。

        综上所述,将新节点的 next 指针设置为 NULL 是维护链表结构完整性和正确处理后续输入的必要步骤,它明确了当前链表的结尾,同时为后续的插入操作提供了正确的链表状态。

        单链表插入逻辑里,每次插入一个新节点时,都要把这个新节点视为当前链表的最后一个节点,并且将其 next 指针设为 NULL。下面为你详细解释原因:

单链表结构特点

        单链表是一种线性数据结构,由一系列节点构成,每个节点包含数据域和指向下一个节点的指针域。链表的末尾节点没有后续节点,所以其 next 指针要设为 NULL,以此来标志链表的结束。这是单链表的基本规则,保证了链表结构的清晰性和可维护性。

相关文章:

  • DNS负载均衡和CDN的区别
  • CentOS 7 修改锁屏时间为永不
  • ADI ADRV902x的射频模拟信号输入输出端口的巴伦匹配
  • 暗物质卯引力挂载技术
  • [模型选择与调优]机器学习-part4
  • 电子电器架构 --- 新能源高压上下电那点事一文通
  • Kubernetes生产实战(十三):灰度发布与蓝绿发布实战指南
  • 2025年客运从业资格证备考单选练习题
  • sh脚本多卡顺序执行训练文件
  • Java 开发者 Linux 学习指南
  • 零件画图实战提升案例(下)
  • 最速下降法和梯度下降法的异同
  • sql注入漏洞的对抗
  • 深入探究 InnoDB 的写失效问题
  • 《操作系统真象还原》第十三章——编写硬盘驱动程序
  • JSON 在 Java 中的应用:手动生成与使用库的对比
  • IBM BAW(原BPM升级版)使用教程第八讲
  • 2025年数维杯赛题C题专家 组委会C题专家疑集锦
  • TCP的连接管理
  • C语言_函数hook方案
  • 重庆大学:对学术不端行为“零容忍”,发现一例、查处一例
  • 体坛联播|郑钦文收获红土赛季首胜,国际乒联公布财报
  • 人民日报刊文:守护“技术进步须服务于人性温暖”的文明底线
  • 韩德洙成为韩国执政党总统大选候选人
  • 长期对组织隐瞒真实年龄,广元市城发集团原董事韩治成被双开
  • 古埃及展进入百天倒计时,闭幕前168小时不闭馆