数据结构——线性表

来源:互联网 发布:oracle默认数据库 编辑:程序博客网 时间:2024/05/16 06:02

                                            线性表     

                                  

一.线性表的逻辑结构

线性表的定义

线性表:简称表,是nn≥0)个具有相同类型的数据元素的有限序列。

线性表的长度:线性表中数据元素的个数。
空表:长度等于零的线性表,记为:L=( )。
非空表记为:L=(a1,a2 , …,ai-1,ai,,an)

其中,ai1≤in)称为数据元素;

下角标 i表示该元素在线性表中的位置或序号 。

线性表的特性

有限性:线性表中数据元素的个数是有穷的。

相同性:线性表中数据元素的类型是同一的

顺序性:线性表中相邻的数据元素ai-1ai之间存在序偶关系(ai-1,ai),即ai-1ai的前驱,aiai-1的后继;a1无前驱,an无后继,其它每个元素有且仅有一个前驱和一个后继。
线性表的抽象数据类型定义

ADT List

Data

      线性表中的数据元素具有相同类型,

      相邻元素具有前驱和后继关系

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

    后置条件:表不变

进一步说明:

(1)线性表的基本操作根据实际应用是而定;

(2)复杂的操作可以通过基本操作的组合来实现;

(3)对不同的应用,操作的接口可能不同。

二.线性表的顺序存储结构及实现

顺序表——线性表的顺序存储结构

存储结构是数据及其逻辑结构在计算机中的表示;

存取结构是在一个数据结构上对查找操作的时间性能的一种描述。

顺序表是一种随机存取的存储结构”的含义为:在顺序表这种存储结构上进行的查找操作,其时间性能为O(1)

顺序表的实现——无参构造函数   操作接口:SeqList( )

顺序表的实现——有参构造函数  操作接口:SeqList(DataType a[ ],int n)

顺序表的实现——插入                操作接口: void Insert(inti,DataType x)

顺序表的实现——删  除               操作接口:DataType Delete(inti)

顺序表的实现——按位查找          操作接口:DataType Get(inti)

顺序表的实现——按值查找          操作接口:int Locate(DataType x )

顺序表的优缺点

顺序表的优点:

⑴ 无需为表示表中元素之间的逻辑关系而增加额外的存储空间;

⑵ 随机存取:可以快速地存取表中任一位置的元素。

顺序表的缺点:

⑴ 插入和删除操作需要移动大量元素;

⑵ 表的容量难以确定,表的容量难以扩充;

⑶ 造成存储空间的碎片

三.线性表的链接存储结构及实现

单链表:线性表的链接存储结构。

存储思想:用一组任意(连续、不连续、零散分布)的存储单元存放线性表的元素。

存储特点:

1.逻辑次序和物理次序不一定相同。

2.元素之间的逻辑关系用指针表示。

单链表是由若干结点构成的

单链表的结点只有一个指针域

data:存储数据元素

next:存储指向后继结点的地址

头指针:指向第一个结点的地址。

尾标志:终端结点的指针域为空。

 

单链表的实现——遍历操作     操作接口:void PrintList( );

单链表的实现——按位查找       操作接口:DataType Get(inti);

实现——按值查找

单链表的实现———插入         操作接口:void Insert(inti,DataType x);

 

单链表的实现———构造函数   操作接口:LinkList(DataType a[ ],int n)

 

单链表的实现———删除           操作接口:DataType Delete(inti);

单链表的实现——析构函数        操作接口:~LinkList( );

算法设计的一般步骤:

第一步:确定入口(已知条件)、出口(结果)

第二步:根据一个小实例画出示意图

第三步:① 正向思维:选定一个思考问题的起点,逐步提出问题、解决问题 ② 逆向思维:从结论出发分析为达到这个结论应该先有什么 ③ 正逆结合

第四步:写出顶层较抽象算法,分析边界情况

第五步:验证第四步的算法

第六步:写出具体算法

第七步:进一步验证,手工运行

循环链表

将单链表的首尾相接,将终端结点的指针域由空指针改为指向头结点,构成单循环链表,简称循环链表。

循环链表——插入

双链表:在单链表的每个结点中再设置一个指向其前驱结点的指针域。

双链表的操作——插入    操作接口:void Insert(DulNode<DataType> *p, DataType x)

双链表的操作——删除    操作接口:DataType Delete(DulNode<DataType> *p)

四. 顺序表和链表的比较

存储分配方式比较

1.顺序表采用顺序存储结构,即用一段地址连续的存储单元依次存储线性表的数据元素,数据元素之间的逻辑关系通过存储位置来实现。

2.链表采用链接存储结构,即用一组任意的存储单元存放线性表的元素,用指针来反映数据元素之间的逻辑关系。
按位查找:
顺序表的时间为(1),是随机存取
链表的时间为(n),是顺序存取

插入和删除:

顺序表需移动表长一半的元素,时间为(n)
链表不需要移动元素,在给出某个合适位置的指针后,插入和删除操作所需的时间仅为(1)

空间性能是指某种存储结构所占用的存储空间的大小

结点的存储密度:

 顺序表:结点的存储密度为1(只存储数据元素),没有浪费空间;
    链表:结点的存储密度<1(包括数据域和指针域),有指针的结构性开销。

结构的存储密度:

顺序表:需要预分配存储空间,如果预分配得过大,造成浪费,若估计得过小,又将发生上溢
链表:不需要预分配空间,只要有内存空间可以分配,单链表中的元素个数就没有限制

结论

⑴若线性表需频繁查找却很少进行插入和删除操作,或其操作和元素在表中的位置密切相关时,宜采用顺序表作为存储结构;若线性表需频繁插入和删除时,则宜采用链表做存储结构。

⑵当线性表中元素个数变化较大或者未知时,最好使用链表实现;而如果用户事先知道线性表的大致长度,使用顺序表的空间效率会更高。

总之,线性表的顺序实现和链表实现各有其优缺点,不能笼统地说哪种实现更好,只能根据实际问题的具体需要,并对各方面的优缺点加以综合平衡,才能最终选定比较适宜的实现方法。

五.线性表的其它存储方法

 

静态链表

静态链表:数组来表示单链表,用数组元素的下标来模拟单链表的指针。

间接寻址

间接寻址:是将数组和指针结合起来的一种方法,它将数组中存储数据元素的单元改为存储指向该元素的指针

 

 

0 0