线性表的顺序存储结构是把线性表中的所有元素按照其逻辑顺序依次存储到从计算机存储器中指定存储位置开始的一块连续的存储空间中。我们称之为顺训表。
这里我们采用一个类模板SqListClass<T>来定义顺序表,其中包含data和length等数据成员,其声明:
template <class T>
class SqListClass{ //顺序表类模板
T *data; //存放顺序表中的元素
int length; //存放顺序表长度
public:
SqListClass(); //构造函数
~SqListClass(); //析构函数
void CreateList(T a[], int n); //由a数组中元素建立顺序表
void DispList(); //输出顺序表L中的所有元素
int ListLength(); //求顺序表的长度
int GetElem(int i); //求顺序表中序号的元素值
int LocateElem(T e); //按元素值查找其序号
bool ListInsert(int i, T e); //插入数据元素
bool ListDelete(int i); //删除数据元素
};
下面是顺序表基本运算的实现:
1、建立顺序表
该运算是将给定的含有若干个元素的数组a的每个元素依次放入到顺序表中,并将其长度n付给顺序表的length数据成员。
该算法时间复杂度为O(n),n表示顺序表中元素个数
template <class T>
void SqListClass<T>::CreateList(T a[], int n){ //由a中的元素建立顺序表
int i;
for (i = 0; i < n; i++)
data[i] = a[i];
length = n;
}
2、顺序表的初始化和销毁
该算法时间复杂度为O(n),n表示顺序表中元素个数
template <typename T>
SqListClass<T>::SqListClass(){ //构造函数
data = new T[MaxSize]; //为data分配长度为MaxSize的空间
length=0; //初始时置length为0
}
template <typename T>
SqListClass<T>::~SqListClass(){ //析构函数
delete[]data; //释放data分配的空间
}
3、输出顺序表:DispList()
该算法依次输出顺序表中各数组元素的值,该算法时间复杂度为O(n),n表示顺序表中元素个数
template<typename T>
void SqListClass<T>::DispList(){ //输出顺序表中的所有元素
int i;
if (length > 0){
for (i = 0; i < length; i++)
cout << data[i] << " "; //扫描顺序表中的各元素值
cout << endl;
}
}
4、求顺序表的长度
返回顺序表长度,即元素个数,该算法时间复杂度为O(1)
template<typename T>
int SqListClass<T>::ListLength(){ //求顺序表的长度
return length;
}
5、求顺序表中某个数据元素值:GetElem(i,e)
用i表示逻辑序号,当逻辑序号i正确时返回data[i-1],否则返回false,该算法时间复杂度为O(n),n表示顺序表中元素个数
template<typename T>
int SqListClass<T>::GetElem(int i){ //求顺序表中某序号的元素值
if (i<1 || i>length)
return false; //参数错误返回false
return data[i - 1]; //成功找到元素的返回
}
6、按元素查找:LocateElem(e)
查找一个与e值相等的元素值,并返回它的逻辑序号。该算法时间复杂度为O(n),n表示顺序表中元素个数
template<typename T>
int SqListClass<T>::LocateElem(T e){ //按元素值查找其序号
int i = 0;
while (i < length&&data[i] != e)
i++; //查找元素e
if (i >= length)
return 0; //未找到时返回0
else return i + 1; //找到后返回其逻辑号
}
7、插入数据元素:ListInsert(i,e)
可以在线性表中的任何一个位置插入一个指定元素,并调整其他元素的位置
该算法时间主要在元素移动上,平均时间复杂度为O(n)
template<class T>
bool SqListClass<T>::ListInsert(int i, T e){ //插入数据元素
int j;
if (i<1 || i>length + 1)
return false; //参数错误时返回false
for (j = length; j >= i; j--) //将data[i-1]及后面的元素后移一个位置
data[j] = data[j-1]; //插入元素e
data[i - 1] = e;
length++; //顺序表长度增加1
return true; //成功插入返回true
}
8、删除数据元素:ListDelete(i,e)
删除逻辑序号为i的元素,删除算法和插入类似,平均时间复杂度为O(n)
template<class T>
bool SqListClass<T>::ListDelete(int i){ //删除数据元素
int j;
if (i<1 || i>length)
return false; //参数错误时返回false
for (j = i - 1; j < length - 1; j++)
data[j] = data[j + 1]; //将data[i]之后的元素前移一个位置
length--; //长度减1
return true; //成功删除返回true
}
添加主测试函数来验证:
//created by kong at 2019-11-17
#include<iostream>
using namespace std;
const int MaxSize = 100;
template <class T>
class SqListClass{ //顺序表类模板
T *data; //存放顺序表中的元素
int length; //存放顺序表长度
public:
SqListClass(); //构造函数
~SqListClass(); //析构函数
void CreateList(T a[], int n); //由a数组中元素建立顺序表
void DispList(); //输出顺序表L中的所有元素
int ListLength(); //求顺序表的长度
int GetElem(int i); //求顺序表中序号的元素值
int LocateElem(T e); //按元素值查找其序号
bool ListInsert(int i, T e); //插入数据元素
bool ListDelete(int i); //删除数据元素
};
template <class T>
void SqListClass<T>::CreateList(T a[], int n){ //由a中的元素建立顺序表
int i;
for (i = 0; i < n; i++)
data[i] = a[i];
length = n;
}
template <typename T>
SqListClass<T>::SqListClass(){ //构造函数
data = new T[MaxSize]; //为data分配长度为MaxSize的空间
length=0; //初始时置length为0
}
template <typename T>
SqListClass<T>::~SqListClass(){ //析构函数
delete[]data; //释放data分配的空间
}
template<typename T>
void SqListClass<T>::DispList(){ //输出顺序表中的所有元素
int i;
if (length > 0){
for (i = 0; i < length; i++)
cout << data[i] << " "; //扫描顺序表中的各元素值
cout << endl;
}
}
template<typename T>
int SqListClass<T>::ListLength(){ //求顺序表的长度
return length;
}
template<typename T>
int SqListClass<T>::GetElem(int i){ //求顺序表中某序号的元素值
if (i<1 || i>length)
return false; //参数错误返回false
return data[i - 1]; //成功找到元素的返回
}
template<typename T>
int SqListClass<T>::LocateElem(T e){ //按元素值查找其序号
int i = 0;
while (i < length&&data[i] != e)
i++; //查找元素e
if (i >= length)
return 0; //未找到时返回0
else return i + 1; //找到后返回其逻辑号
}
template<class T>
bool SqListClass<T>::ListInsert(int i, T e){ //插入数据元素
int j;
if (i<1 || i>length + 1)
return false; //参数错误时返回false
for (j = length; j >= i; j--) //将data[i-1]及后面的元素后移一个位置
data[j] = data[j-1]; //插入元素e
data[i - 1] = e;
length++; //顺序表长度增加1
return true; //成功插入返回true
}
template<class T>
bool SqListClass<T>::ListDelete(int i){ //删除数据元素
int j;
if (i<1 || i>length)
return false; //参数错误时返回false
for (j = i - 1; j < length - 1; j++)
data[j] = data[j + 1]; //将data[i]之后的元素前移一个位置
length--; //长度减1
return true; //成功删除返回true
}
int main(){
int a[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 10 };
SqListClass<int> s1;
s1.CreateList(a, 10);
cout << "s1顺序表元素:";
s1.DispList();
cout << "s1顺序表长度:" << s1.ListLength() << endl;
cout << "查找元素值的位置:" << s1.LocateElem(5) << endl;
cout << s1.GetElem(4) << endl;
s1.ListInsert(3, 20);
s1.DispList();
cout << "s1顺序表长度:" << s1.ListLength() << endl;
s1.ListDelete(5);
s1.DispList();
cout << "s1顺序表长度:" << s1.ListLength() << endl;
return 0;
}
运行结果: