考研408--数据结构--day3--链表

在这里插入图片描述
(以下内容全部来自上述课程)

请添加图片描述

单链表的定义

请添加图片描述

1. 什么是单链表

上次我们说顺序表是名单上的学号,那么单链表就是教室中的散乱的同学们按随机的座位坐好。
座位随机,就代表数据不是连续的,也就是前后桌的学号不是连在一起的,但是还是可以利用学号(这里相当于地址)找到具体同学。
请添加图片描述

2. 用代码定义一个单链表

typedef:数组类型重命名。
单链表的定义:头插法or尾插法
需要插入的东西就是结点,单链表就是好多个结点连在一起的东西,所以我们先看结点定义。

2.1 结点定义

结点=数据域+指针域;
数据域:存储它的数据元素
指针域:存储下一个结点的地址值
请添加图片描述
新结点分配空间–>头结点√
请添加图片描述

  • typedef struct LNode LNode; typedef struct LNode *LinkList;
  • LNode * L; LinkList L;
    互相对照,一开始定义中有*,用这个别名定义别的就可以省略*
    一句话就是,竖着看,都只存在一个*
    请添加图片描述
    请添加图片描述

2.2 单链表定义

请添加图片描述

3. 实现

3.1 不带头结点的单链表

不带头结点,初始化单列表的时候就可以不给它分配空间。
定义结点–>初始化空单链表–>无头结点
请添加图片描述

3.2 带头结点的单链表

定义结点–>初始化空单链表–>有头结点(分配空间)
请添加图片描述

3.3 对比

更倾向带头结点的定义方法。
请添加图片描述

4. 小结

请添加图片描述

单链表的插入删除

请添加图片描述

1. 插入

1.1 按位序插入

1.1.1 带头结点

记忆:取代某个结点的位置(i),就是在这个结点之前的位置(i-1)插入新的结点。
请添加图片描述

  • LNode *s =(LNode *)malloc(sizeof(LNode));:分配新的内存给s指针指的位置
  • s->data =e;:表示s的数据域是元素e
  • s->next=p->next;:使p指针原本指的位置,赋值给s指针即将指向的位置,next就是指向的下一个结点
    p原本指的是a1,也就是让s指向a1,也就是图中连起来的绿色的线
  • p->next=s;:让p指向的下一个结点变为s,也就是图中黄色的线

补充:

  • A->data:A的数据域
  • ->:指向
  • next:下一个结点
  • A->next:A指向的下一个结点
    请添加图片描述
    如果绿色和黄色颠倒顺序:
  • 先是p指向的下一个结点变为s
  • 然后把p指向的下一个结点赋值给s指向的下一个结点
  • 就变成了s指向自己本身
  • 所以千万不可以颠倒顺序!!!
    请添加图片描述
    如果插入在最后的位置,插入的元素指向的位置就是NULL。
    请添加图片描述
    如果插入的位置超出了单链表的长度,就会直接返回false。
    请添加图片描述
    平均时间复杂度是O(n)
    请添加图片描述
1.1.2 不带头结点

请添加图片描述
插在表头就需要改变头指针(之前指向a1,现在指向插入的元素)

  • LNode *s =(LNode *)malloc(sizeof(LNode));:分配插入元素的内存
  • s->data =e;:表明s的数据域是元素e。
  • s->next=L;:L是头指针,所以就是L指向的下一个结点赋值给s指向的下一个结点,就是s指向a1,也就是绿线。
  • L=S;:L指向s,也就是图中的黄线。
    请添加图片描述
    如果插入之后的位置是第一个位置之后,因为没有头结点,所以每次都需要记录一下指针此时指向的是哪个结点,除此之外,其余的和头结点的插入代码一模一样。
    请添加图片描述

1.2 指定结点的后插操作

因为分配的空间比较随机,所以前后空间存不存在都是随机的,有的时候就可能分配失败。
请添加图片描述
如果分配失败,就直接返回false;
如果分配成功(右下角):

  • s->data =e;:s的数据域是元素e
  • s->next=p->next;:p指向的下一个结点赋值给s的指向的下一个结点(加一个往后指的线)
  • p->next=s;:p指向的下一个结点变为s(加一个前面往这里的线)
    请添加图片描述

1.3 指定结点的前插操作

指定结点的前插操作,就需要先找到他的前一个结点,然后再进行操作。
但是没办法找到前一个结点,循环太浪费时间,所以就找到此指定节点A的后一个结点B,在他们两个之间插入你想插入的结点X,然后把指定节点A和插入结点X的数据域互换一下,和指定节点的前插操作就是等价的效果。
请添加图片描述

  • 大体思路是,x–>y,想变成e–>x–>y,就先变成x–>e–>y,xe互换数据域,变为e–>x–>y。
  • s->next=p->next;:p指向的下一个结点赋值给s指向的下一个结点(绿线)
  • p->next=s;:p指向的下一个结点变为s
  • s->data=p->data;:p的数据域赋值给s的数据域
  • p->data=e;:p的数据域变为元素e
    请添加图片描述

2. 删除

2.1 按位序删除

请添加图片描述
如果删除的是最后一个结点,就需要把它前一个结点指向NULL。
请添加图片描述

2.2 指定结点的删除

同样,先删掉指定节点的后一个结点,然后把指定节点的数据域,改成刚刚删除的结点的数据域。
嗯,无关先后顺序,差不多这个意思。
请添加图片描述

  • LNode *q=p->next;:p指向的后一个结点赋值给q结点
  • p->data=p->next->data;:p指向的下一个结点的数据域赋值给p的数据域
  • p->next=q->next;:q指向的下一个结点赋值给p指向的下一个结点
    请添加图片描述
    请添加图片描述

3. 小结

请添加图片描述
请添加图片描述

单链表的查找

只讨论带头结点的情况!
请添加图片描述

1. 按位查找

如果i=0,直接返回头指针的位置。
请添加图片描述
如果i=8,也就是查找单链表长度之外的元素,会直接返回p。
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述

2. 按值查找

按值查找,就是条件中用数据域进行判断。
请添加图片描述
请添加图片描述
请添加图片描述

3. 小结

请添加图片描述

单链表的建立

请添加图片描述

1. 尾插法

定义结点–>初始化单链表
请添加图片描述
其实就是带头结点的指定节点的后插操作。
请添加图片描述
请添加图片描述
请添加图片描述

2. 头插法

逆向建立单链表,然后每次都是尾插,最后再倒过来。
请添加图片描述
请添加图片描述
请添加图片描述

3. 小结

请添加图片描述

双链表

所有操作就是比单链表多了一个prior,不再赘述。
请添加图片描述

1. 初始化

增加了一个prior,前一个结点。
请添加图片描述

2. 插入

请添加图片描述
请添加图片描述

3. 删除

请添加图片描述

4. 遍历

请添加图片描述

5. 小结

请添加图片描述

循环链表

请添加图片描述

1. 循环单链表

请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述

2. 循环双链表

请添加图片描述

2.1 初始化

请添加图片描述

2.2 插入

请添加图片描述

2.3 删除

请添加图片描述

4. 小结

请添加图片描述

静态链表

请添加图片描述

1. 什么是静态链表

请添加图片描述

2. 用代码定义一个静态链表

请添加图片描述
请添加图片描述

2. 简述基本操作的实现

请添加图片描述
请添加图片描述

4. 小结

请添加图片描述

顺序表 vs 链表

请添加图片描述

1. 逻辑结构

请添加图片描述

2. 存储结构

请添加图片描述

3. 基本操作

请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述

4. 选择?

请添加图片描述

5. 小结

请添加图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值