1.顺序表简介
顺序表是在计算机内存中以数组的形式保存的线性表,线性表的顺序存储是指用一组地址连续的存储单元依次存储线性表中的各个元素、使得线性表中在逻辑结构上相邻的数据元素存储在相邻的物理存储单元中,即通过数据元素物理存储的相邻关系来反映数据元素之间逻辑上的相邻关系,采用顺序存储结构的线性表通常称为顺序表。顺序表是将表中的结点依次存放在计算机内存中一组地址连续的存储单元中。(百度百科)
2.顺序表的基本操作
- 插入值
在进行插值操作时,插入位置的后端元素需要整体后移一位,再进行插入,如图所示:
- 删除值
进行删除值操作时,从被删除元素下一位开始,依次前移,如图所示:
- 遍历
顺序表时基于数组的,直接使用for循环对数据域进行遍历即可,不赘述。
顺序表几乎所有操作都是与插入,删除,遍历相关的。
3.顺序表的C++实现
- 类型构造
template <class DataType>
class SeqList //顺序表类
{
public:
SeqList(); //无参数构造
SeqList(DataType a[],int n); //将数组转化构造
~SeqList(); //析构
int length(); //返回长度
DataType get(int i); //按位查值
int locate(DataType x); //按值查位
void insert(int i,DataType x); //插值
void del_loc(int i); //按位删值
void del_data(DataType x); //按值删值
void clear(); //清空
protected: //使用protected方便栈与队列类继承
DataType *data; //数据域
int len; //长度
};
- 构造与析构
template <class DataType>
SeqList<DataType>::SeqList() //无参数构造
{
cout << "SeqList Constructed!" << endl;
len = 0;
}
template <class DataType>
SeqList<DataType>::SeqList(DataType a[],int n) //以数组为参数进行构造
{
if(n > maxn)
throw "Parameter Error!"; //超范围报错
for(int i = 0;i < n;i++)
data[i]=a[i];
len = n;
cout << "SeqList Constructed!" << endl;
}
template <class DataType> //析构
SeqList<DataType>::~SeqList()
{
cout << "SeqList Distructed!" << endl;
}
- 返回长度
template <class DataType>
int SeqList<DataType>::length()
{
return len; //直接返回长度即可
}
- 按位查值与按值查位
template <class DataType>
DataType SeqList<DataType>::get(int i) //按位查值
{
if(i < 1 && i > len)
throw "Location Error!"; //位置错误
else return data[i - 1];
}
template <class DataType>
int SeqList<DataType>::locate(DataType x) //按值查位
{
for(int i = 0;i < len;i++) //依次遍历即可
if(data[i]==x)
return i+1;
return 0;
}
- 插入值
template <class DataType>
void SeqList<DataType>::insert(int i,DataType x) //第一个参数为需要插入的位置,第二个参数为插入的数据
{
if(len >= maxn)
throw "Overflow!"; //溢出
if(i < 1 || i > len + 1)
throw "Location Error!";
for(int j = len;j >= i;j--) //从后往前依次讲数据后移一位以免发生覆盖
data[j] = data[j - 1];
data[i - 1] = x;
len++; //长度加一
}
- 按位删值以及按值删值
template <class DataType>
void SeqList<DataType>::del_loc(int i) //按位删值
{
int x;
if(len == 0)
throw "Underflow!";
if(i<1 || i>len)
throw "Location Error!";
x = data[i - 1];
for(int j = i;j < len;j++) //指定位置之后后继依次前移,自动覆盖要删除的值
data[j - 1] = data[j];
len--;
}
template <class DataType>
void SeqList<DataType>::del_data(DataType x) //按值删值
{
for(int i = 0;i < len;++i)
if(data[i] == x)
del_loc(i + 1); //遍历到要删的值再按位删值
}
- 清空
template <class DataType>
void SeqList<DataType>::clear()
{
len = 0; //长度时其他操作的重要依据,这里使长度为0即可完成清空
cout << "SeqList cleared!" << endl;
}
- 调试
void SeqList_debug()
{
SeqList<int> a;
int sw;
cout << "SeqList Options:\n1.Insert data\n2.Delete data by location\n3.Delete data by value\n4.Find data by location\n5.Find location by data\n6.Get the length\n7.Clear the list\n8.Print the list\n9.Exit\n";
while (cin >> sw)
{
if (sw == 1)
{
int loc,da;
cout << "Please input the location and data: ";
cin >> loc >> da;
a.insert(loc,da);
}
else if (sw == 2)
{
int loc;
cout << "Please input the location: ";
cin >> loc;
a.del_loc(loc);
}
else if (sw == 3)
{
int x;
cout << "Please input the data: ";
cin >> x;
a.del_data(x);
}
else if (sw == 4)
{
int loc,x;
cout << "Please input the location: ";
cin >> loc;
x = a.get(loc);
cout << x << endl;
}
else if (sw == 5)
{
int loc,x;
cout << "Please input the data: ";
cin >> x;
loc = a.locate(x);
cout << loc << endl;
}
else if (sw == 6)
{
cout << a.length() << endl;
}
else if (sw == 7)
{
a.clear();
}
else if (sw == 8)
{
for(int i = 1;i <= a.length();++i)
cout << a.get(i) << " ";
cout << endl;
}
else
{
break;
}
cout << "SeqList Options:\n1.Insert data\n2.Delete data by location\n3.Delete data by value\n4.Find data by location\n5.Find location by data\n6.Get the length\n7.Clear the list\n8.Print the list\n9.Exit\n";
}
}
4.小结
顺序表访问的时间复杂度低,但是进行插入和删除时时间复杂度高,并且容易浪费储存空间,在使用时需要做好选择。
总提纲:《数据结构》期末提纲小结