顺序表
线性表的顺序存储结构:线性表
特点:线性表的顺序存储是指用一组地址连续的存储单元依次存储线性表中的各个元素,
作用:线性表中在逻辑结构上相邻的数据元素存储在相邻的物理存储单元中,即通过数据元素物理存储的相邻关系来反映数据元素之间逻辑上的相邻关系。
顺序存储的实现:一维数组存储顺序表中的数据。
设顺序表的每个元素占用 c 个存储单元,则第 i 个元素的存储地址为:
LOC ( a i ) = LOC ( a 1 ) + ( i - 1 ) × c
容易看出,顺序表中数据元素的存储地址时其序号的线性函数,只要确定了存储顺序表的其实地址,计算任意一个元素的存储地址的时间是先等的,具有这一特点的存储结构成为随机存取结构。
顺序表的实现:
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 ( ) ; // 遍历线性表,按序号依次输出各元素
};
构造函数:
定义了两个构造函数:
①无参构造函数(构造一个空的顺序表)
SeqList ( ) {length=0;}
构造一个非空的顺序表
SeqList ( T a[ ], int n ) ; // 有参构造函数
②有参构造函数的实现:
将长度为n的一维数组中的元素依次传入到data中。
template <class T>
SeqList<T>:: SeqList(T a[], int n)
{
if (n>MaxSize) throw "参数非法";
for (int i=0; i<n; i++)
data[i]=a[i];
length=n;
}
插入算法:
1 如果顺序表已满,抛出上溢异常
2 如果元素插入位置不存在,抛出位置异常
3 将最后一个元素至第i个元素(i为插入位置)向后移动一个位置
4 将元素插入到i位置
5 将顺序表的长度增1
template <class T>
void SeqList<T>::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++;
}
删除算法:
线性表的删除运算是指将表的第i(1≤i≤n)个元素删去,使长度为n的线性表(e1,…, ei-1,ei,ei+1,…,en)变成长度为n-1的线性表(e1,…, ei-1, ei+1,…,en)。
1 如果顺序表已空,抛出下溢异常
2 如果元素删除位置不存在,抛出位置异常
3 取出被删除的元素
4 将下标为i,i+1…n-1的元素一次移到i-1,i,…n-2的位置
5 将顺序表的长度减1,返回被删除的元素
template <class T>
T SeqList<T>::Delete(int i){
int j;
T x;
if (length==0) 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;
}
查找算法:
①按位置查找:
template <class T>
T SeqList<T>::Get(int i)
{
if (i<1 && i>length) throw "查找位置非法";
else return data[i-1];
}
②按值查找:
template <class T>
int SeqList<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) 由于顺序表要求占用连续的存储空间,存储分配只能预先进行静态分配,因此当表长变化较大时,难以确定合适的存储规模。