第二章线性表
基本内容是:
1.线性表的逻辑结构
2.线性表的顺序存储及实现
3.线性表的链接存储及实现
4.顺序表和单链表的比较
5.线性表的其他存储及实现
数据元素之间的关系是什么?
线性表(
Linear
List )的定义
线性表:简称表,是n(n≥0)个具有相同类型的数据元素的有限序列。
线性表的长度:线性表中数据元素的个数。空表:长度等于零的线性表,记为:L=( )。
非空表记为:L=(a1,
a2 , …, ai-1, ai , …, an)
其中,ai(1≤i≤n)称为数据元素;下角标 i 表示该元素在线性表中的位置或序号。
线性表的特性
1.有限性:线性表中数据元素的个数是有穷的。
2.相同性:线性表中数据元素的类型是同一的。
3.顺序性:线性表中相邻的数据元素ai-1和ai之间存在
序偶关系(ai-1, ai),即ai-1是ai的前驱, ai是ai-1的后继; a1
无前驱,an无后继,其它每个元素有且仅有一个前驱和一个后继。
线性表中的数据元素具有相同类型,相邻元素具有前驱和后继关系
Operation
InitList
前置条件:表不存在输入:无功能:表的初始化输出:无后置条件:建一个空表
线性表的抽象数据类型定义
DestroyList
前置条件:表已存在输入:无功能:销毁表输出:无
后置条件:释放表所占用的存储空间
Length
前置条件:表已存在输入:无功能:求表的长度
输出:表中数据元素的个数后置条件:表不变
线性表的抽象数据类型定义
Get
前置条件:表已存在输入:元素的序号i
功能:在表中取序号为i的数据元素
输出:若i合法,返回序号为i的元素值,否则抛出异常后置条件:表不变
Locate
前置条件:表已存在输入:数据元素x
功能:在线性表中查找值等于x的元素输出:若查找成功,返回x在表中的序号,否则返回0 后置条件:表不变
线性表的抽象数据类型定义
Insert
前置条件:表已存在输入:插入i;待插x
功能:在表的第i个位置处插入一个新元素x 输出:若插入不成功,抛出异常
后置条件:若插入成功,表中增加一个新元素
Delete
前置条件:表已存在输入:删除位置i
功能:删除表中的第i个元素
输出:若删除成功,返回被删元素,否则抛出异常后置条件:若删除成功,表中减少一个元素
线性表的抽象数据类型定义
Empty
前置条件:表已存在输入:无功能:判断表是否为空输出:若是空表,返回1,否则返回0 后置条件:表不变
PrintList
前置条件:表已存在输入:无功能:遍历操作,按序号依次输出表中元素输出:表的各数据元素后置条件:表不变 endADT
进一步说明:
(1)
线性表的基本操作根据实际应用而定;
(2)
复杂的操作可以通过基本操作的组合来实
现;
– 假设利用两个线性表LA和LB分别表示两个集合A和 B(即:线性表中的数据元素即为集合中的成员),现要求一个新的集合A=AUB:
Get(one from B)-Locate(in A)-Insert(to A)?
(3)
对不同的应用,操作的接口可能不同。
– 删除表中的值为x的元素
– 删除表中的第i个元素
存储结构是数据及其逻辑结构在计算机中的表示;存取结构是在一个数据结构上对查找操作的时间性能的一种描述。
“顺序表是一种随机存取的存储结构”的含义为:在顺序表这种存储结构上进行的查找操作,其时间性能为O(1)。
伪代码
-
如果表满了,则抛出上溢异常;
-
如果元素的插入位置不合理,则抛出位置异常;
-
将最后一个元素至第i个元素分别向后移动一个位置;
-
将元素x填入位置i处;
-
表长加1;
顺序表的实现——插入
仿照顺序表的插入操作,完成:
-
分析边界条件;
-
分别给出伪代码和C++描述的算法;
-
分析时间复杂度。
顺序表的优缺点
¾顺序表的优点:
⑴无需为表示表中元素之间的逻辑关系而增加额外的存储空间;
⑵随机存取:可以快速地存取表中任一位置的元素。
¾顺序表的缺点:
⑴插入和删除操作需要移动大量元素;
⑵表的容量难以确定,表的容量难以扩充;
⑶造成存储空间的碎片。
单链表:线性表的链接存储结构。
存储思想:用一组任意的存储单元存放线性表的元素。
存储特点:
- 逻辑次序和物理次序不一定相同。
2.元素之间的逻辑关系用指针表示。
单链表 …
0200
头指针:存储第一个结点的地址,
0208 即,指向第一个结点。
尾标志:终端结点的指针域为空。
空表 0300 first=NULL
单链表
头结点:在单链表的第一个元素结点之前附设一个类型相同的结点,以便空表和非空表处理统一。
核心操作(关键操作):工作指针后移。从头结点(或开始结点)出发,通过工作指针的反复后移而将整个单链表“审视”一遍的方法称为扫描(或遍历)。
单链表的实现——遍历
操作接口: void PrintList();
int LinkList:: PrintList()
{ p=first->next; while (p!=NULL)
{ cout<data;
p=p->next;
}
}
单链表的实现——求线性表的长度操作接口: int Length();
int LinkList:: Length()
{
p=first->next; count=0;
while (p!=NULL)
{ count++;
p=p->next;
} return count;
}
查找成功 查找失败
™核心操作(关键操作):工作指针后移——遍历
单链表的实现——按位查找算法描述——伪代码
-
工作指针p初始化;
累加器j初始化; -
循环直到p为空或p指向第i个结点
2.1 工作指针p后移;
2.2 累加器j加1;
- 若p为空,则第i个元素不存在,抛出查找位置异常;否则查找成功,返回结点p的数据元素;
单链表的实现——按位查找算法描述——C++描述
template
T LinkList::Get(int i)
{ p=first->next; j=1;
while (p!=NULL && j<i)
{ p=p->next;
j++;
}
if (p==NULL) throw “位置”;
else return p->data;
单链表的实现———插入算法描述——伪代码
-
工作指针p初始化;累加器j清零;
-
查找第i-1个结点并使工作指针p指向该结点;
-
若查找不成功,说明插入位置不合理,抛出插入位置异常;否则,
3.1 生成一个元素值为x的新结点s;
3.2 将新结点s插入到结点p之后;
单链表的实现———删除算法描述——伪代码
1.工作指针p初始化;累加器j清零;
-
查找第i-1个结点并使工作指针p指向该结点;
-
若p不存在或p不存在后继结点,则抛出位置异常;否则,
3.1 暂存被删结点和被删元素值;
3.2 摘链,将结点p的后继结点从链表上摘下;
3.3 释放被删结点;
3.4 返回被删元素值;