一、概念
1、线性结构是数据结构里最基础也是最简单的一种数据结构类型,其中典型的一种叫“线性表”。
2、“线性表(Linear List)”:由同类型数据元素构成有序序列的线性结构
- 表中元素个数称为线性表的长度
- 线性表没有元素时,称为空表
- 表起始位置称表头,表结束位置称表尾
3、线性表的抽象数据类型描述:
- 类型名称:线性表(List)
- 数据对象集:线性表是 n(>=0)个元素构成的有序序列(a1,a2,····,an)
- 操作集:线性表L属于List,整数i表示位置,元素X属于 ElementType,其基本操作如下:
二、线性表的顺序存储实现方式——利用数组的连续存储空间顺序存放线性表的个元素
其数据结构如下:
线性表顺序存储方式(数据)的初始化、查找、插入和删除操作:
(1)初始化(建立空的线性表)
(2)查找
(3)插入(在第 i (1<=i<=n+1) 个位置上插入一个值为X的新元素)
数组下标从零开始,所以插入到第数组的 i-1 个位置。插入时的做法是先移动,往后移,然后再插入。
(4)删除
三、线性表的链式存储实现
不要求逻辑上相邻的两个元素物理上也相邻;通过“链”建立起数据元素之间的逻辑关系。
插入、删除不需要移动数据元素,只需要修改“链”。
1、比方说有这样一个链表,链表每个结点都是一个结构,这个结构里至少有两个分量:
数据和next指针指向下一个结点位置,如下图所示:
2、主要操作实现
(1)求表长(遍历链表)
知道链表的头指针 PtrL,并且它是单向链表,遍历每个元素求出链表长度。时间复杂度是表的长度O(n)
(2)查找
(3)插入(在第 i-1(1<=i<=n+1) 个结点后插入一个值为X的新结点)
- malloc函数构造一个新结点,用s指向
- 再找到链表的第i-1个结点,用p指向
- 然后修改指针,插入结点(p之后插入新结点是s)
通过两个赋值语句可以修改指针方向。顺序不能更换,如果更换会造成s->Next指向s,从而不能正确完成插入。
代码分析:
List Insert( ElementType X, int i, List Ptrl )
{
List p,s;
if( i==1 ){ //新结点插入在表头
s = (List)malloc(sizeof(struct LNode)); //申请地址空间、填装结点数据和下一个结点的指针
s->Data = X;
s->Next = Ptrl;
return s; //返回新表头指针
}
p = FindKth(i-1, Ptrl); //查找第 i-1 个结点
if( p==NULL ){
printf("参数i错"); //第i-1个不存在,不能插入
return NULL;
}else{
s = (List)malloc(sizeof(struct LNode)); //申请、填装结点
s->Data = x;
S->Next = p->Next; //新结点插入在第i-1个结点的后面
p->Next = s;
return Ptrl;
}
(4)删除(删除链表的第i(1<=i<=n) 个位置上的结点)
- 先找到链表的第i-1个结点,用p指向;
- 再用指针s指向要被删除的结点(p的下一个结点);
- 然后修改指针,删除s所指结点;
- 最后释放s所指向结点的空间。
3、广义表(Generalized List)
- 广义表是线性表的推广;
- 对于线性表而言吗,n个元素都是基本的单元素;
- 广义表中,这些元素不仅可以是单元素也可以是另一个广义表
4、多重链表
参考资料:浙大《数据结构》公开课——陈越、何钦铭