线性表的逻辑结构
线性表的定义
是零个或多个具有相同类型的数据元素的有限序列。
数据元素的个数定义为线性表的 长度 。长度等于零时称为空表,一个非空表通常记为
L = ( a 1 , a 2 ,……, a n )
其中, a i *( 1 ≤ i ≤ n )*称为数据元素,
下标 i 表示该元素在线性表中的位置或序号, 称元素 a i 位于表的第 i 个位置,或称 a i 是表中的第 i 个元素。
具体实例:英文字母表
线性表的逻辑结构
线性表的定义
是零个或多个具有相同类型的数据元素的有限序列。
数据元素的个数定义为线性表的 长度 。长度等于零时称为空表,一个非空表通常记为
L = ( a 1 , a 2 ,……, a n )
其中, a i ( 1 ≤ i ≤ n )称为数据元素,
下标 i 表示该元素在线性表中的位置或序号, 称元素 a i 位于表的第 i 个位置,或称 a i 是表中的第 i 个元素。
线性表的抽象数据类型定义
InitList
前置条件:线性表不存在
输入:无
功能:线性表的初始化
输出: 无
后置条件:一个空的线性表
DestroyList
前置条件:线性表已存在
输入:无
功能:销毁线性表
输出:无
后置条件:释放线性表所占用的存储空间
Length
前置条件:线性表已存在
输入:无
功能:求线性表的长度
输出: 线性表中数据元素的个数
后置条件:线性表不变
Get
前置条件:线性表已存在
输入:元素的序号 i
功能:在线性表中取序号为 i 的数据元素
输出:如果序号合法,返回序号为 i 的元素值,否则抛出异常
后置条件:线性表不变
Locate
前置条件:线性表已存在
输入:数据元素 x
功能:在线性表中查找值等于 x 的元素
输出:如果查找成功,返回元素 x 在表中的序号,否则返回 0
后置条件:线性表不变
Insert
前置条件:线性表已存在
输入:插入位置 i ;待插元素 x
功能:在线性表的第 i 个位置处插入一个新元素 x
输出:若插入不成功,抛出异常
后置条件:若插入成功,表中增加了一个新元素
Delete
前置条件:线性表已存在
输入:删除位置 i
功能:删除线性表中的第 i 个元素
输出:若删除成功,返回被删元素,否则抛出异常
后置条件:若删除成功,表中减少了一个元素
Empty
前置条件:线性表已存在
输入:无
功能:判断线性表是否为空表
输出:若是空表,返回 1 ,否则返回 0
后置条件:线性表不变
PrintList
前置条件:线性表已存在
输入:无
功能:按位置的先后次序依次输出线性表中的元素
输出:线性表的各个数据元素
后置条件:线性表不变
//也可不按此命名 因为需要自己定义!
线性表的顺序存储结构-顺序表
特点:线性表的顺序存储是指用一组地址连续的存储单元依次存储线性表中的各个元素,
作用:线性表中在逻辑结构上相邻的数据元素存储在相邻的物理存储单元中,即通过数据元素物理存储的相邻关系来反映数据元素之间逻辑上的相邻关系。
顺序存储的实现:一维数组存储顺序表中的数据
const int Maxsize=100;
template <class T>
classlList{
private:
T data[MaxSize]; // 存放数据元素的数组
int length; // 线性表的长度
public:
lList ( ) ;// 无参构造函数
lList ( T a[ ], int n ) ; // 有参构造函数
~lList( ) { } // 析构函数为空
int Length ( ) {return length;} // 求线性表的长度
int Locate ( T x ) ; // 按值查找,求线性表中值为 x 的元素序号
void Insert ( int i, T x ) ; // 在线性表中第 i 个位置插入值为 x 的元素
T Get ( int i ); // 按位查找,取线性表的第 i 个元素
T Delete ( int i ) ; // 删除线性表的第 i 个元素
void PrintList ( ) ; // 遍历线性表,按序号依次输出各元素
};
定义了两个构造函数:
//无参构造函数(构造一个空的顺序表)
lList ( ) {length=0;}
//构造一个非空的顺序表
lList ( T a[ ], int n ) ; // 有参构造函数
//将a[i]的值转化为data[i]的
template <class T>
lList<T>::lList(T a[], int n)
{
if (n>MaxSize) throw "参数非法";
for (int i=0; i<n; i++)
data[i]=a[i];
length=n;
}
插入操作:
线性表的插入运算是指在表的第i (1≤i≤n+1)个位置,插入一个新元素e,
具体算法:
1 如果顺序表已满,抛出上溢异常
2 如果元素插入位置不存在,抛出位置异常
3 将最后一个元素至第i个元素(i为插入位置)向后移动一个位置
4 将元素插入到i位置
5 将顺序表的长度增1
具体实现:
template <class T>
voidlList<T>::Insert(int i, T x){
int j;
if (length>=MaxSize) throw "上溢";//1
if (i<1 || i>length+1) throw "位置";//2
for (j=length; j>=i; j--)
data[j]=data[j-1]; //3
data[i-1]=x;//4
length++;//5
}
删除操作:
线性表的删除运算是指将表的第i(1≤i≤n)个元素删去
具体算法:
1 如果顺序表已空,抛出下溢异常
2 如果元素删除位置不存在,抛出位置异常
3 取出被删除的元素
4 将下标为i,i+1…n-1的元素一次移到i-1,i,…n-2的位置
5 将顺序表的长度减1,返回被删除的元素
具体实现:
template <class T>
TlList<T>::Delete(int i){
int j;
T x;
if (length==0) throw "下溢";//1
if (i<1 || i>length) throw "位置";//2
x=data[i-1];//3
for (j=i; j<length; j++)
data[j-1]=data[j]; //4
length--;
return x;//5
}
查找操作:
两种查找方法
按位置查找,即查找指定位置上的元素
按值查找,即查找指定的值在顺序表中的位置
按位置查找具体实现
:
template <class T>
TlList<T>::Get(int i)
{
if (i<1 && i>length) throw "查找位置非法";
else return data[i-1];
}
按值查找具体实现:
template <class T>
intlList<T>::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.可方便地随机存取表中的任一元素。
缺点:
1.插入,删除运算不方便,需要移动大量的数据
2.线性表长度变化大时,难以确定存储空间的容量
链式存储分配:
根据线性表的长度动态的申请存储空间,以解决顺序存储中存在的存储空间难以确定的问题,减少对空间的浪费,减少产生的存储空间的碎片
链式存储结构的实现
单链表
双向链表
循环链表
等