线性表(List):零个或多个数据元素的有限序列。
顺序存储结构、链式存储结构。
顺序存储结构:
用一段地址连续的存储单元依次存储线性表的数据元素。用一维数组实现。
//线性表的顺序存储的结构
#define MAXSIZE 20
typedef int ElemType;
typedef struct
{
ElemType data[MAXSIZE];
int length;
}SqList;
线性表的长度小于等于数组的长度。
地址计算:LOC(ai)=LOC (a1)+(i-1)*c 一个元素占c个存储单元
1、获得元素操作
2、插入操作
3、删除元素操作
操作前均需要检查元素位置合法性。
优点:
无需额外存储空间;
快速存取表中任意位置的元素
缺点:
插入和删除移动大量元素;
表的长度变化大时难以确定存储空间;
造成存储空间碎片
链式存储结构
用任意存储单元 存储线性表的元素。
单链表:
每个结点中 包含 一个数据域 和 一个指针域。
第一个结点为头结点,数据域可以不存储任何信息或者存储表长度等附加信息。
头指针具有标识作用,常冠以链表的名字,无论链表是否为空,头指针必存在。
j++:核心思想:工作指针后移 (while)
1、单链表的读取
2、单链表的插入
3、单链表的删除
4、单链表的整表创建(头插法、尾插法)
5、整表删除(头结点开始释放)
当频繁查找,用顺序存储结构
频繁插入删除,用单链表结构
元素个数变化较大或者根本不知道多大,用单链表
静态链表:
用数组表述的链表,无指针。(游标实现法)
以前学习的各种链表都是由指针实现的,链表中结点的分配和回收(即释放)都是由系统提供的标准函数malloc和free动态实现的,故称之为动态链表。但是有的高级语言,如BASIC、FORTRAN等,没有提供”指针”这种数据类型,此时若想采用链表做存储结构,就必须使用”游标”来模拟指针,由程序员自己编写”分配结点”和”回收结点”的过程。
用游标实现链表,其方法是:定义一个较大的结构数组作为备用结点空间(即存储池)。当申请结点时,每个结点应含有两个域:data域和cursor域。data域用来存放结点的数据信息,需注意的是,此时的cursor域不在是指针而是游标指示器,游标指示器指示其后继结点在结构数组中的相对位置(即数组下标)。第0个元素的cur设置为 第一个空闲空间的位置;最后一个元素的cur设置为第一个有值元素的位置;最后一个有值元素的cur设置为0.
1、静态链表初始化
2、静态链表的插入操作
3、静态链表的删除操作
优点:插入删除时不需要移动元素,只改游标
缺点:没有解决表长度难以确定的问题,失去了顺序存储随机存取的特性
循环链表:
终端的空指针指向头结点。
循环链表中存在一个头结点。
判断一个循环链表是否为空,判断p->next是否等于头结点。(单链表 判断p->next 是否为空)
两个循环链表的合并问题,丢掉一个头结点。
双向链表:
每个结点有两个指针域,一个指向直接前驱,一个指向直接后继。
插入和删除时要改变两个指针变量。注意改变顺序!!!