@第二章 线性表

2.1 线性表的逻辑结构
1.线性表(Linear List )的定义
1.线性表:简称表,是n(n≥0)个具有相同类型的数据元素的有限序列。
2.线性表的长度:线性表中数据元素的个数。
3.空表:长度等于零的线性表,记为:L=( )。
4.非空表记为:L=(a1, a2 , …, ai-1, ai,…, an),其中,ai(1≤i≤n)称为数据元素;下角标i 表示该元素在线性表中的位置或序号。
2.线性表的特性
1.有限性:线性表中数据元素的个数是有穷的。
2.相同性:线性表中数据元素的类型是同一的。
3.顺序性:线性表中相邻的数据元素ai-1和ai之间存在序偶关系(ai-1, ai),即ai-1是ai的前驱,ai是ai-1的后继;a1无前驱,an无后继,其它每个元素有且仅有一个前驱和一个后继。
3.线性表的抽象数据类型定义
ADT List
Data
线性表中的数据元素具有相同类型,相邻元素具有前驱和后继关系
Operation
InitList
前置条件:表不存在输入:无功能:表的初始化输出:无后置条件:建一个空表
Destroy
List
前置条件:表已存在输入:无功能:销毁表输出:无后置条件:释放表所占用的存储空间
Length
前置条件:表已存在输入:无功能:求表的长度输出:表中数据元素的个数后置条件:表不变
Get
前置条件:表已存在输入:元素的序号i功能:在表中取序号为i的数据元素输出:若i合法,返回序号为i的元素值,否则抛出异常后置条件:表不变
Locate
前置条件:表已存在输入:数据元素x功能:在线性表中查找值等于x的元素输出:若查找成功,返回x在表中的序号,否则返回0后置条件:表不变
Insert
前置条件:表已存在输入:插入i;待插x功能:在表的第i个位置处插入一个新元素x输出:若插入不成功,抛出异常后置条件:若插入成功,表中增加一个新元素
Delete
前置条件:表已存在输入:删除位置i功能:删除表中的第i个元素输出:若删除成功,返回被删元素,否则抛出异常后置条件:若删除成功,表中减少一个元素
Insert
前置条件:表已存在输入:插入i;待插x功能:在表的第i个位置处插入一个新元素x输出:若插入不成功,抛出异常后置条件:若插入成功,表中增加一个新元素
Delete
前置条件:表已存在输入:删除位置i功能:删除表中的第i个元素输出:若删除成功,返回被删元素,否则抛出异常后置条件:若删除成功,表中减少一个元素 endADT
进一步说明:( 1 ) 线性表的基本操作根据实际应用而定;(2)复杂的操作可以通过基本操作的组合来实现;–假设利用两个线性表LA和LB分别表示两个集合A和B(即:线性表中的数据元素即为集合中的成员),现要求一个新的集合A=AUB:Get(one from B)-Locate(in A)-Insert(to A)?(3)对不同的应用,操作的接口可能不同。–删除表中的值为x的元素–删除表中的第i个元素
2.2 线性表的顺序存储结构及实现
4.顺序表——线性表的顺序存储结构
存储要点:1用一段地址连续的存储单元
2依次存储线性表中的数据元素
5.存储结构和存取结构
存储结构是数据及其逻辑结构在计算机中的表示;存取结构是在一个数据结构上对查找操作的时间性能的一种描述。
6.顺序表的实现——无参构造函数
template
SeqList:: SeqList( )
{ length=0;}
7.顺序表的实现——有参构造函数
8.顺序表的实现——按位查找
算法描述:template
T SeqList::Get( inti )
{if (i>=1 && i<=length) return data[i-1];}
9.顺序表的实现——按值查找
template
intSeqList::Locate(T x)
{
for (i=0; i<length; i++)
if (data[i]x) return i+1;
return 0;
}
10.顺序表的实现——遍历
template
void SeqList::PrintList()
{
for (i=0; i<length; i++)
cout<<data[i];
}
11.顺序表的实现——插入
1算法描述——伪代码
1. 如果表满了,则抛出上溢异常;
2. 如果元素的插入位置不合理,则抛出位置异常;
3. 将最后一个元素至第i个元素分别向后移动一个位置;
4. 将元素x填入位置i处;
5. 表长加1
2算法描述——C++描述
template
void SeqList::Insert(inti, T x)
{if (length>=MaxSize)throw “上溢”;
if (i<1 | | i>length+1)throw “位置”;
for(j=length; j>=i; j–)data[j]=data[j-1];
data[i-1]=x;length++;}
3时间性能分析
最好情况(i=n+1):
基本语句执行0次,时间复杂度为O(1)。
最坏情况(i=1):
基本语句执行n次,时间复杂度为O(n)。
12.顺序表的实现——删除
1算法描述——C++描述
template
T SeqList::Delete(inti)
{if (length
MaxSize)throw “下溢";
if (i<1 | | i>length)throw “位置”;
x=data[i-1];
for(j=i;; j<length; j++)data[j-1]=data[j];
length–;return x;}
13.顺序表的优缺点
?顺序表的优点:
⑴无需为表示表中元素之间的逻辑关系而增加额外的存储空间;
⑵随机存取:可以快速地存取表中任一位置的元素。
?顺序表的缺点:
⑴插入和删除操作需要移动大量元素;
⑵表的容量难以确定,表的容量难以扩充;
⑶造成存储空间的碎片。
2.3 线性表的链接存储结构及实现
1单链表:线性表的链接存储结构。
2存储思想:用一组任意的存储单元存放线性表的元素。
3存储特点:1.逻辑次序和物理次序不一定相同。
2.元素之间的逻辑关系用指针表示。
4单链表是由若干结点构成的;单链表的结点只有一个指针域。
data:存储数据元素next:存储指向后继结点的地址
5单链表的结点结构:
template
structNode
{T data;
Node *next;};
6头指针:存储第一个结点的地址,即,指向第一个结点。
尾标志:终端结点的指针域为空。
7头结点:在单链表的第一个元素结点之前附设一个类型相同的结点,以便空表和非空表处理统一。
8单链表类的声明
template
class LinkList
{
public:
LinkList( );
LinkList(Ta[ ], intn);
~LinkList( );
intLength( );
T Get(inti);
intLocate(T x);
void Insert(inti, T x);
T Delete(inti);
void PrintList( );
private:
Node *first;};
单链表的实现——遍历
单链表的实现——求线性表的长度
单链表的实现——按位查找
template T LinkList::Get(inti) {p=first->next; j=1; while (p!=NULL && j<i) {p=p->next; j++; }if (
pNULL) throw “位置”;else return p->data;
单链表的实现——按值查找
template
intLinkList::Locate(T x)
{
p=first->next; j=1;
while §{
if(p->data
x)return j;
else
{ p=p->next; j++; }
}
return 0;}
单链表的实现———插入
s=new Node; s->data=x;
s->next=p->next; p->next=s;
单链表的实现———构造函数
template
LinkList:: LinkList(Ta[ ], intn)
{
first=new Node;
first->next=NULL;
for (i=0; i<n; i++)
{
s=new Node;
s->data=a[i];
s->next=first->next;
first->next=s; }}
单链表的实现———删除
q=p->next; x=q->data;
p->next=q->next; delete q;
单链表的实现——析构函数
template
LinkList:: ~LinkList( )
{
p=first;
while (p!=NULL)
{
q=p;
p=p->next;
delete q;
}
9.循环链表——插入
开始结点:first->next
终端结点:将单链表扫描一遍,时间为O(n)
2.4 顺序表和链表的比较
1存储分配方式比较
?顺序表采用顺序存储结构,即用一段地址连续的存储单元依次存储线性表的数据元素,数据元素之间的逻辑关系通过存储位置来实现。
?单链表采用链接存储结构,即用一组任意的存储单元存放线性表的元素。用指针来反映数据元素之间的逻辑关系。
2时间性能比较
时间性能是指实现基于某种存储结构的基本操作(即算法)的时间复杂度。
按位查找:?顺序表的时间为O(1),是随机存取;?单链表的时间为O(n),是顺序存取。插入和删除:?顺序表需移动表长一半的元素,时间为O(n);?单链表不需要移动元素,在给出某个合适位置的指针后,插入和删除操作所需的时间仅为O(1)。
3空间性能比较
空间性能是指某种存储结构所占用的存储空间的大小。
结点的存储密度:?顺序表中每个结点的存储密度为1(只存储数据元素),没有浪费空间;?单链表的每个结点的存储密度<1(包括数据域和指针域),有指针的结构性开销。
整体结构:?顺序表需要预分配存储空间,如果预分配得过大,造成浪费,若估计得过小,又将发生上溢;?单链表不需要预分配空间,只要有内存空间可以分配,单链表中的元素个数就没有限制。
4结论
⑴若线性表需:•查找多,插入和删除少,或•操作和元素在表中的位置密切相关宜采用顺序表作为存储结构;若线性表需频繁插入和删除时,则宜采用单链表做存储结构。⑵若线性表中元素个数变化较大或未知时,最好使用单链表实现;如果事先知道线性表的大致长度,使用顺序表的空间效率会更高
总之,线性表的顺序实现和链表实现各有其优缺点,不能笼统地说哪种实现更好,只能根据实际问题的具体需要,并对各方面的优缺点加以综合平衡,才能最终选定比较适宜的实现方法。
5

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值