C语言——链表

什么是链表

知识点

什么是链表——数据结构——数据存放的思想

数组:

特点:在一片连续的地址空间中,存放着某些特点的数据,将这些数据集合在这片地址空间。

缺点:增加减少元素需要挪动整个数据地址,运算量比较大,而且数组一开始就申请了空间,需要用到malloc等。

       链表每一项都是一个结构体,地址空间不连续

注意点:

定义一个结构体,里面包含一个变量,以及一个指向结构体变量的指针

       定义三个变量

       为了使得三个数据有联系,像数组一样,数据处于连续的空间,因此用指针存放下一个数据的地址。

  1. 静态创建链表动态遍历

  1. 静态动态链表区别

静态创建链表是在编译时就确定了链表的大小,需要手动为每个节点分配内存空间,不支持动态扩容和缩容。而动态创建链表则是在运行时动态地为每个节点分配内存空间,支持动态扩容和缩容。

静态创建链表的优点是空间利用率高,不需要额外的内存分配操作,但缺点是不够灵活,无法满足实际应用中动态变化的需求;而动态创建链表的优点是灵活性高,可以根据实际需求动态调整链表大小,但缺点是空间利用率较低,需要额外的内存分配操作。

在实际应用中,一般情况下都采用动态创建链表的方式,因为它更加灵活、方便。同时,在使用动态创建链表时,需要注意释放不需要的节点的内存空间,以防止内存泄漏问题。

链表新添加一个数据:

比较笨的办法,指针一个一个指向下一个

利用循环以及函数封装

传上来t1的地址,用*head来接收

定义数据时候t1的下一个指针指向t2地址。。。只有t4的指针是空的,因此只需要找到第一个元素,一个一个遍历下去,判断传上来的指针是否为空,如果为空就结束循环。

统计链表节点个数以及链表查找

统计链表节点:

定义一个函数,判断传上来的地址是否为空,为空就结束循环,不为空就加一

链表查找:

函数封装,形参中包含首元素地址以及需要查找元素数值,循环判断,如果传上来的值能够在链表遍历时在链表中找到,那么久i返回1,如果找不到,就返回0;

     用一个变量去承接函数返回的值,如果是0,则没找见,如果是1,则找见了。

链表从指定节点插入新节点

指定节点后方插入:

方法一:

封装函数:形参包括(首元素地址,需要插入的数据,以及指向这个数据的指针)

正常遍历链表,循环中,如果输入的数据(该数据为链表中数据)在循环中找见了,那就让新的数据下一个地址指向原来数据的下一个地址,原来数据下一个地址指向新添加的数据;

       正常新建一个数据,打印

方法2:

循环遍历,直到找到这个数让循环停下来,if语句,如果没有找到就返回0说明在链表中没找到,插入失败,剩下的跟前面一样。

指定节点前方插入新节点:

第一个元素前面插入

第一个节点=》会导致目标链表头发生变化,函数封装,定义一个返回类型为指针的函数,将返回的指针给到链表头,去引起main函数链表头发生变化,如果需要插入的数字被遍历找到后,新数据的下一个地址指向旧的头数字地址,并返回新的头数字地址;

定义一个指针head,链表创建完成后,使其为链表头的地址,

常规前面插入

前面判断是否是第一个元素,如果不是,进入到下一条程序,循环内判断p->next不为空,不为空,

封装函数(前方插入)

       a第一种情况:在首元素前面插入

       p与head都指向1这个元素,p->data(head->data) = 1,插入一个新的的,让new(指针)指向p/head,插入成功后return new作为新的链表头,根据new去遍历链表;

       b第二种情况:在第二个元素插入

       if语句:当前插入位置的data跟第一个不相等,执行下一条语句

while:p->next是否为空,是,驶入循环

if:p->next->data是否是我要找的数字,是,让新元素下一个指向p->next,再让p->指向新元素地址,头元素没有受到影响,返回头元素进行遍历;

       c第三种情况:既不是第一个,也不是第二个

       if语句:当前插入位置的data跟第一个不相等,执行下一条语句

while:p->next是否为空,是,驶入循环

       if:p->next->data是否是我要找的数字,不是,跳出if语句,进行遍历,p->2这个元素,p->next->data(此时经过指针偏移,p指向2,p的下一个就是3)是否是我们要找的元素,是,返回头元素地址进行遍历;

       ·d第四种情况:没有我们要找的元素

     打印没有元素,插入失败,返回头元素地址。

链表的删除/修改

知识点:

a 如果是第一个节点,改变首元素地址,head往后走;

b 非第一个元素,绕过他,直接指向下一个元素p->next = p->next->next

修改:

图解:

如果是删除头元素

如果是删除中间元素

判断下一个是否是我们要删除的,如果是,让p的下一个指向下下一个,即p->next=p->next->next

链表动态创建之头插法

知识点:

新节点进来,默认头节点,头永远是新元素,,类似于栈

注意点:

优化前:

定义一个指针,循环,不停的给new开辟一个结构体大小的空间(需要强转为指针类型),提示输入,输入,中途判断输入中是否有0,如果有,则清空刚开辟的空间,并返回head,打印链表,判断传上来的头是否是空的,如果是,就让head成为新的数据,再进行循环,新的数据下一个指向head,给head重新赋值new

优化后

创建链表与往后偏移分开,创建链表数据做完以后,调用偏移函数,将head与new传过去,让偏移函数判断,偏移函数运行结束return head到创建函数,继续循环,只有输入为0才会将创建函数head返回主函数,好处是可以单独插入。

偏移

创建

  • 29
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值