线性表链式存储结构定义
线性表的链式存储结构的特点是用一组任务的存储单元存储线性表的数据元素,这组存储单元可以是连续的,也可以是非连续的。这就意味着,这些数据元素可以存储在内存未被占用的任意位置。
线性表的顺序存储结构中,每个数据元素只需要存储数据元素信息就可以了。现在链式结构中,除了要存储数据元素外,还要存储它的后继元素的存储地址。
为了表示每个数据元素ai与其直接后继元素的ai+1之间的逻辑关系,对数据元素ai来说,除了存储其本身的信息之外,还需存储一个指示其后继的信息(即直接后继的存储位置)。我们把存储数据元素的域称为数据域,把存储直接后继位置的域成为指针域。指针域中存储的信息称作指针或链。这两部分信息组成数据元素ai的存储映像,成为结点(Node)。
n个结点链结成一个链表,即为线性表(a1,a2,…ai,ai+1,…,an)的链式存储结构,因为此链表的每个结点中只包含一个指针域,所以叫做单链表。
线性表链式存储结构
1 | typedef int ElementType; |
data为数据域,next为指针域
线性表链式存储结构的插入
插入操作算法描述
- p初始指向链表头结点,迭代p,最终使得p指向第i-1个结点
- 如果p为NULL,表示第i-1个结点不存在,返回FAILURE
- 创建新结点,令p的后继是新结点,返回SUCCESS
1 | Status listInsert(LinkedList linkedList, int i, ElementType e) { |
线性表链式存储结构的删除
删除操作算法描述
- p初始指向链表头结点,迭代p,最终使得p指向第i-1个结点
- 如果p为NULL,则返回FAILURE
- tmp指向第i个结点,p的后继为第i个结点的后继
- 释放掉tmp指向的结点所占内存,返回SUCCESS
1 | Status listDelete(LinkedList linkedList, int i, ElementType *e) { |
线性表链式存储结构的逆转
反转算法描述
设置3个指针,cur指向当前要操作的元素(操作当前元素的指针域),pre指向前驱元素,next指向后继元素,next用于保存暂存后继元素的位置信息
- 使得next指向cur的后继元素,因为下一步要修改cur元素的指针域,如果没有这一步,将找不到cur的后继元素
- 将cur指向的当前元素的指针域修改为指向pre指向的元素
- 使得pre指向cur指向的元素
- 令cur与next的指向相同
- 循环结束后,创建新的头结点(当然用之前的头节点也可以,只要修改指针域令其指向pre指向的结点),令头结点的指针域指向pre指向的结点
- 释放原来头结点占用的内存空间
1 | LinkedList listReverse(LinkedList list) { |
线性表链式存储结构的查找
算法描述
- p指向第一个结点,j=1
- 迭代直到j=i,退出循环
- 如果p为NULL则返回FAILURE
- 用e来返回第i个元素的数据
1 | Status listSearch(LinkedList list, int i, ElementType *e) { |
线性表链式存储结构查找倒数第k个结点
算法描述
- 设置两个指针p1,p2初始都指向第1个结点
- p2向右移动k个位置
- p1,p2一起向右移动,直至p2移动到末尾
- 返回p1,即倒数第k个结点
1 | Node* listTheBackKthNode(LinkedList list, int k) { |
线性表链式存储结构查中间结点
算法描述
与上述查找倒数第k个结点的算法一样,只不过倒数第几个,要根据链表长度计算一下而已,不再赘述
1 | Node* listTheMiddleNode(LinkedList list) { |
线性表链式存储完整代码
1 |
|