2.1 线性表
线性表的概念
数据结构中最简单的就是线性表。定义为
n
(
n
≥
0
)
n(n\geq0)
n(n≥0)个数据元素的一个有限的序列。记为:
L
=
(
a
1
,
.
.
.
,
a
i
,
a
i
+
1
,
.
.
.
,
a
n
)
L = (a_1, ..., a_i, a_{i+1}, ..., a_n)
L=(a1,...,ai,ai+1,...,an)
,其中
a
1
a_1
a1为表头,
a
n
a_n
an为表尾。
在线性结构中,这种邻接关系是1对1的,每个结点至多只有一个直接前驱并且至多只有一个直接后继。
线性表的存储表示有两种:顺序存储方式(顺序表)和链表存储方式。
2.2 顺序表
顺序表是线性表基于数组的存储表示。
定义和特点
定义:把线性表中所有表项按照其逻辑顺序以此存储到从计算机存储中指定存储位置开始的一块连续的存储空间中。
特点:(1)在顺序表中,各个表项的逻辑顺序与其存放的物理顺序一致,即第i个表项存储于第i个物理位置。(2)对顺序表中所有表项,既可以进行顺序访问也可以进行随机访问。
假设顺序表A的起始存储位置为
L
o
c
(
1
)
Loc(1)
Loc(1),第i个表项的存储位置为
L
o
c
(
i
)
Loc(i)
Loc(i),则有:
L
o
c
(
i
)
=
L
o
c
(
1
)
+
(
i
−
1
)
×
s
i
z
e
o
f
(
T
)
Loc(i) = Loc(1) + (i-1) \times sizeof(T)
Loc(i)=Loc(1)+(i−1)×sizeof(T)
类定义及其操作
搜索和定位操作
插入与删除操作
顺序表的性能分析
-
搜索算法
搜索的平均数据比较次数 A C N = 1 + n 2 ACN = \frac{1+n}{2} ACN=21+n -
插入运算
平均数据移动次数 A M N = n 2 AMN = \frac{n}{2} AMN=2n -
删除运算
平均数据移动次数 A M N = n − 1 2 AMN = \frac{n-1}{2} AMN=2n−1
2.3 单链表(重要)
链表是线性表基于链接方式的存储表示。
单链表的概念
单链表是最简单的一种链表表示,也叫作线性链表。用它表示线性表时,通过指针表示结点间的逻辑关系。
因此单链表中的一个存储结点包含两个部分:data(数据域)+ link(指针域)。
链表的第一个结点的地址可通过链表的头指针找到,链表的最后一个结点没有后继,link域中存放一个空指针NULL。所以对单链表中任一结点的访问必须首先根据头指针找到第一个结点,再按指针顺序往下找。
单链表特点:长度可以很方便地进行扩充。每个结点的存储位置可以任意安排,不需要相邻,对链表操作时仅需要修改相关结点的指针域即可。
单链表的类定义
通常使用两个类(链表的结点类和链表类)协同表示单链表。
常用的是用struct定义LinkNode类。
struct LinkNode{
int data;
LinkNode *link;
};
class List{
private:
LinkNode *first;
public:
//链表操作
...
...
};
单链表的插入与删除
插入有三种情况
删除有两种情况
带附加头结点的单链表
为实现方便,增加一个“附加头结点”,它的data域中可以不存储任何信息,也可以存放一个特殊标志或表长。
因此相应的插入和删除操作也有所变化。在带附加头结点的单链表中插入时,不必区分在何处插入,可以统一使用:
newNode->link = current->link; current->link = newnode;
而在带附加头结点的单链表中删除时,可以统一使用:
del = current->link; current->link = del->link; delete del;
单链表的模板类 (重要,要掌握)
类定义、链表长度、搜索、定位、取值、赋值、插入、删除、创建单链表(头插法、尾插法)
2.4 线性链表的其他变形
循环链表
链表的尾结点的link域中不是NULL,而是存放一个指向链表开始结点的指针。
著名问题:约瑟夫问题
双向链表
双向链表中每个结点都有两个链指针,一个指向结点的直接前驱,一个指向结点的直接后继。
顺序表与链表之间的优缺点比较