二十一、线性表的链式存储结构
1、线性表的链式存储结构
顺序存储结构线性表的最大问题是:插入和删除需要移动大量的元素!如何解决?
2、链式存储的定义
为了表示每个数据元素与其直接后继元素之间的逻辑关系;
数据元素除了存储本身的信息外,还需要存储其直接后继的信息。
3、链式存储逻辑结构
- 基于链式存储结构的线性表中,每个结点都包含数据域和指针域
- 数据域:存储数据元素本身
- 指针域:存储相邻结点的地址
4、专业术语的统一
- 顺序表
- 基于顺序存储结构的线性表
- 链表
- 基于链式存储机构的线性表
- 单链表:每个结点只包含直接后继的地址信息
- 循环链表:单链表中的最后一个结点的直接后继为第一个结点
- 双向链表:单链表中的结点包含直接前驱和后继的地址信息
- 基于链式存储机构的线性表
5、链表中的基本概念
- 头结点
- 链表中的辅助结点,包含指向第一个数据元素的指针
- 数据结点
- 链表中代表数据元素的结点,表现形式为:(数据元素,地址)
- 尾结点
- 链表中的最后一个数据结点,包含的地址信息为空
6、单链表中的结点定义
7、单链表中的内部结构
头结点在单链表中的意义是:辅助数据元素的定位,方便插入和删除操作;因此,头结点不存储实际的数据元素
8、在目标位置处插入数据元素
1. 从头结点开始,通过current指针定位到目标位置
2. 从堆空间申请新的Node结点
3. 执行操作:
9、在目标位置处删除数据元素
1. 从头结点开始,通过current指针定位到目标位置
2. 使用toDel指针指向需要删除的结点
3. 执行操作:
10、编程实验:图解插入与删除
11、小结
- 链表中的数据元素在物理内存中无相邻关系
- 链表中的结点都包含数据域和指针域
- 头结点用于辅助数据元素的定位,方便插入和删除操作
- 插入和删除操作需要保证链表的完整性
二十二、单链表的具体实现
1、课程目标
完成链式存储结构线性表的实现
2、LinkList设计要点
- 类模板,通过头结点访问后继结点
- 定义内部结点类型Node,用于描述数据域和指针域
- 实现线性表的关键操作(增,删,查,等)
3、LinkList的定义
4、编程实验:链表的实现
LinkList.h
5、问题
头结点是否存在隐患?实现代码是否需要优化?
6、头结点的隐患
7、代码优化
insert , remove , get , set 等操作都涉及元素定位。
8、编程实验:链表的优化
LinkList.h
#ifndef LINKLIST_H_
#define LINKLIST_H_
/*******************************************************************************
* Include _Files *
*******************************************************************************/
#include "List.h"
#include "Exception.h"
/*******************************************************************************
* Type Definition *
*******************************************************************************/
namespace DTLib
{
template < typename T >
class LinkList : public List<T>
{
protected:
struct Node : public Object // 结点类
{
Node* next; // 指针域
T value; // 数据域
};
mutable struct : public Object // mutable 突破const的限制而设置,永远处于可变的状态,即使在一个const函数中
{
N