线性表知识总结

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_43633379/article/details/102770491

线性表:
线性表简称表,是n个元素的有限序列。

特点为每个元素仅有一个前驱和后继,第一个元素无前驱,最后一个元素无后继,并且所有的元素的元素类型相同。

线性表跟其他的逻辑结构的数据一样,存储结构分为顺序存储和链式存储。

顺序存储的表称作顺序表,链式存储的表称作链表。
一、线性表的逻辑结构
1、
线性表:是零个或多个具有相同类型的数据元素的有限序列。
非空表:L=(a1,a2,…,an)(ai为数据元素)
2、线性表的抽象数据类型定义
Date
线性表中的数据元素具有相同类型,相邻元素具有前驱和后继关系
Operation
IniList
前置条件:线性表不存在
输入:无
功能:线性表的初始化
输出:无
后置条件:一个空的线性表
DestroyList
前置条件:线性表已存在
输入:无
功能:销毁线性表
输出:无
后置条件:释放线性表所占用的存储空间
Length
前置条件:线性表已存在
输入:无
功能:求线性表的长度
输出:线性表中数据元素的个数
后置条件:线性表不变
Get
前置条件:线性表已存在
输入:元素的序号i
功能:在线性表中取序号为i的数据元素
输出:如果序号合法,返回序号为i的元素值,否则抛出异常
后置条件:线性表不变
Locate
前置条件:线性表已存在
输入:数据元素x
功能:在线性表中查找值等于x的元素
输出:如果查找成功,返回元素x在表中的序号,否则返回0
后置条件:线性表不变
Insert
前置条件:线性表已存在
输入:插入位置i;待插元素x
功能:在线性表的第i个位置处插入一个新元素x
输出:若插入不成功,抛出异常
后置条件:若插入成功,表中增加了一个新元素
Delete
前置条件:线性表已存在
输入:删除位置i
功能:删除线性表中的第i个元素
输出:若删除成功,返回被删元素,否则抛出异常
后置条件:若删除成功,表中减少一个元素
Empty
前置条件:线性表已存在
输入:无
功能:判断线性表是否为空表
输出:若是空表,返回1,否则返回0
后置条件:线性表不变
PrintList
前置条件:线性表已存在
输入:无
功能:按位置的先后次序依次输出线性表中的元素
输出:线性表的各个数据元素
后置条件:线性表不变

二、线性表的顺序存储结构及其实现
1、顺序表
用一组地址连续的存储单元依次存储线性表中的各个元素
作用:通过数据元素物理存储的相邻关系来反映数据元素之间逻辑上的相邻关系
用一维数组存储顺序表中的数据
2、设顺序表中的每个元素占c个存储单元,则第i个元素的存储地址为:
LOC(ai)=LOC(a1)+(i-1)*c
(随机访问):
在这里插入图片描述
3、顺序表的实现
const int Maxsize=100;
template
class SeqList{
private:
T data[MaxSize];//存放数据元素的数组
int length;//线性表的长度
public:
SeqList();//无参构造函数
SeqLIst(T a[],int n);//有参构造函数
~SeqLIst(){}//析构函数为空
int Length(){return length;}//求线性表的长度
T Get(int i);//按位查找,取线性表的第i个元素
int Locate(T x);//按值查找,求线性表中值为x的元素序号
void Insert(int i,T x);//在线性表中第i个位置插入值为x的元素
T Delete(int i);//删除线性表的第i个元素
void PrintList();//遍历线性表,按序号依次输出各元素
};

4、插入操作
线性表的插入运算是指在表的第i(1<=i<=n+1)个位置,插入一个新元素e,使长度为n的线性表变成长度为n+1的线性表
(注意元素移动和顺序表长度增加)
5、插入算法的实现
template
void SeqLIst::Insert(int i,T x){
int j;
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++;
}
5、分析
插在最后不移动元素,时间复杂性为O(1);
插在开头需要移动n个元素,O(n);
6、删除算法的实现
template
void SeqLIst::Delete(int i,T x){
int j;
T x;
if(length==0)throw"下溢";
if(i<1||i>length)throw"位置";
x=data[i-1];
for(j=1;j<length;j++)
data[j-1]=data[j];
length–;
return x;
}
7、分析
在最后删除,O(1);
在开头删除,移动n-1个元素,O(n);
8、顺序表中的查找操作
①按位置查找:查找指定位置上的元素
template
T SeqList::Get(int i)
{
if(i<1&&i>length) throw"查找位置非法";
else return data[i-1];
}
时间复杂度为O(1)
②按值查找:查找指定的值在顺序表中的位置
template
int SeqList::Locate(T x){
for(int i=0;i<length;i++)
if(data[i]==x)
return i+1;//下标为i的元素等于x,返回其序号i+1
return 0;//退出循环,说明查找失败
}

三、线性表的链式存储结构及实现
1、链式存储分配的特点:
根据线性表的长度动态的申请存储空间,以解决顺序存储中存在的存储空间难以确定的问题
2、链式存储结构的实现
单链表、双向链表、循环链表等
3、链表结点数据类型的定义
template
struct Node
{
T data;
Node*next;/此处也可以省略
};
4、单链表的实现
template
class LinkList{
public:
LinkList(){first=new Node;first->next=NULL;}
LinkList(T a[],int n);
~LinkList();
int Length();
T Get(int i);
int Locate(T x);
void Insert(int i,T x);
T Delete(int i);
void PrintList();
private:
Node*first;//单链表的头指针,可以省略
};
5、头插法
6、尾插法

四、顺序表和单链表的比较
1、时间性能的比较
①若线性表的操作主要是进行查找,很少做插入和删除时,宜采用顺序表做存储结构
②对于频繁进行插入和删除的线性表,宜采用链表做存储结构
2、空间性能比较
存储密度=节点数据本身所占的存储量/节点结构所占的存储总量
当线性表的长度变化不大,易于事先确定其大小时,为了节约存储空间,宜采用顺序表作为存储结构

五、线性表的其他存储方法
1、循环链表、
双向链表、
静态链表:插入和删除时不需要移动元素,直接修改指针即可,因此效率高。但是不能按需进行存储空间的分配
2、间接寻址(指针数组)
①线性表的顺序存储的优点:支持随机访问
②线性表的链式存储的优点:插入和删除数据时不需要移动数据
③间接寻址:将指针和数组结合起来的一种方法,他将数组中的存储数据元素的单元改为存储指向该元素的指针

猜你喜欢

转载自blog.csdn.net/qq_43633379/article/details/102770491