数据结构笔记——链表

1. 链表的概念

顺序表 → 静态存储分配 → 事先确定容量

链表 → 动态存储分配 → 运行时分配空间

1.1 单链表:线性表的链接存储结构

存储思想:用一组任意的存储单元存放线性表的元素——不连续、零散分布

1.2 单链表存储特点

  • 逻辑次序和物理次序不一定相同
  • 元素之间的逻辑关系用指针表示

单链表是由若干结点构成的,节点只有一个指针域

1.3 单链表的结点结构

数据结构笔记——链表_第1张图片

  • data:数据域,存储数据元素
  • next:指针域,存储指向后继结点的地址

数据结构笔记——链表_第2张图片

  • Node st; 等价于 struct node st;
  • Link p; 等价于 struct node *p; (p=&st;)
  • Node变成了一个类型,声明一个结构体变量;Link也变成了一个类型,用来声明一个指向结构体的指针

1.4 如何申请一个结点?

p = (Link)malloc(sizeof(Node)); 等价于 p = (struct node *)malloc(sizeof(Node));

1.5 如何引用数据元素?

(*p).data / p -> data

1.6 如何引用指针域?

p -> next

1.7 什么是存储结构?

数据元素之间的逻辑关系的表示,将实际存储地址抽象。

头指针:指向第一个结点的地址

尾标志:终端结点的指针域为空

空表:head=NULL

如何将空表与非空表统一?——引入头结点

头结点:在单链表的第一个元素结点之前附设一个类型相同的节点

2. 单链表的实现

2.1 单链表的遍历操作

操作接口:void displayNode(Link head);

数据结构笔记——链表_第3张图片

 p = p->next语句改成 p++ 能否完成指针后移? 不可以!

链表中结点的存储不是连续的,是零散的!

2.2 求单链表的元素个数

操作接口:int length(Link head);

数据结构笔记——链表_第4张图片

2.3 单链表的查找操作 

数据结构笔记——链表_第5张图片

2.4 单链表的插入操作

操作接口:void insertNode(Link head, int i, DataType x);

数据结构笔记——链表_第6张图片

2.5 创建一个单链表——头插法

操作接口:Link newList(DataType a[], int n);

头插法:将待插入结点插在头结点的后面

数据结构笔记——链表_第7张图片  

2.6 创建一个单链表——尾插法

操作接口:Link newList(DataType a[], int n);

尾插法:将待插入结点插在终端结点的后面

数据结构笔记——链表_第8张图片

每次创建一个结点时,将结点数据域指针域全部初始化,指针域初始化为空

2.7 单链表节点的删除

操作接口:bool deleteNode(Link head, DataType x);

数据结构笔记——链表_第9张图片

2.8 单链表的释放

操作接口:void clearLink(Link head);

数据结构笔记——链表_第10张图片

3. 循环链表

将单链表的首尾相接,将终端结点的指针域由空指针改为指向头结点,构成单循环链表,简称循环链表

循环链表的特点:没有明显的尾端 → 如何避免死循环?——修改循环条件

循环条件:(其他操作和单链表一样,除了循环退出条件)

p != NULL → p != head

p->next != NULL → p->next != head

4. 双向链表

在单链表的每个结点中再设置一个指向其前驱结点的指针域。(占用更多的存储空间)

结点结构:

  • data:数据域,存储数据元素
  • prior:指针域,存储该节点的前趋结点地址
  • next:指针域,存储该节点的后趋结点地址

参考:懒猫老师(数据结构入门)

你可能感兴趣的:(#,数据结构与算法,数据结构,链表,算法)