什么是链表
知识点
什么是链表——数据结构——数据存放的思想
数组:
特点:在一片连续的地址空间中,存放着某些特点的数据,将这些数据集合在这片地址空间。
缺点:增加减少元素需要挪动整个数据地址,运算量比较大,而且数组一开始就申请了空间,需要用到malloc等。
链表每一项都是一个结构体,地址空间不连续
注意点:
定义一个结构体,里面包含一个变量,以及一个指向结构体变量的指针
定义三个变量
为了使得三个数据有联系,像数组一样,数据处于连续的空间,因此用指针存放下一个数据的地址。
-
静态创建链表动态遍历
-
静态动态链表区别
静态创建链表是在编译时就确定了链表的大小,需要手动为每个节点分配内存空间,不支持动态扩容和缩容。而动态创建链表则是在运行时动态地为每个节点分配内存空间,支持动态扩容和缩容。
静态创建链表的优点是空间利用率高,不需要额外的内存分配操作,但缺点是不够灵活,无法满足实际应用中动态变化的需求;而动态创建链表的优点是灵活性高,可以根据实际需求动态调整链表大小,但缺点是空间利用率较低,需要额外的内存分配操作。
在实际应用中,一般情况下都采用动态创建链表的方式,因为它更加灵活、方便。同时,在使用动态创建链表时,需要注意释放不需要的节点的内存空间,以防止内存泄漏问题。
链表新添加一个数据:
比较笨的办法,指针一个一个指向下一个
利用循环以及函数封装
传上来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返回主函数,好处是可以单独插入。
偏移
创建