数据结构学过了模板之后就开始了线性表的学习,线性表又分为简单的顺序存储和链式存储两种方式。两种方法各有长短,根据不同的实际情况定义使用。
线性表的定义:
是零个或多个具有相同类型的数据元素的有限序列。
通常的线性表中有两个元素,一个是存储的数据,另一个是表数据的长度。
顺序存储的特点:
线性表的顺序存储,是指用一维地址连续的存储单元依次存储线性表中的各个元素。
设顺序表的每个元素占用c个存储单元,则第i个元素的存储地址为:
顺序表的作用:
线性表中在逻辑结构上相邻的数据元素存储在相邻的物理存储单元中,即通过数据元素物理存储的相邻关系来反映数据元素之间逻辑上的相邻关系。
顺序存储的实现:
一维数组存储顺序表中的数据。
顺序表定义及相关函数代码:
#include<iostream>
using namespace std;
const int Maxsize = 100;
template <class T>
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(); // 遍历线性表,按序号依次输出各元素
};
int main() { return 0; }
两个构造函数:
SeqList() //定义无参的构造函数,需要使length长度为0
{
length = 0;
}
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;
}
插入操作
为了保证数据的完整,顺序表利用循环将第 i 个位置的数值替换掉,循环只可从数据尾部开始,data[i]=data[i-1]。
线性表的插入运算是指在表的第i (1≤i≤n+1)个位置,插入一个新元素e,使长度为n的线性表 (e1,…,ei-1,ei,…,en) 变成长度为n+1的线性表(e1,…, ei-1,e,ei,…,en)
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++; //长度+1
}
时间复杂度不多做证明,单重循环,时间复杂度为O(n)
删除操作
同样,删除操作为了保证数据不丢失,只可以在第 i 个位置开始循环,向后替换数据。
线性表的删除运算是指将表的第i(1≤i≤n)个元素删去,使长度为n的线性表(e1,…, ei-1,ei,ei+1,…,en)变成长度为n-1的线性表(e1,…, ei-1, ei+1,…,en)。
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++) //从i开始循环,向后替换数据
data[j - 1] = data[j];
length--; //删除操作,长度-1
return x;
}
时间复杂度为O(n)
查找操作
- 按位置查找
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; //退出循环,说明查找失败
}
时间复杂度O(n)
顺序表的特点
由上面的讨论可知, 线性表顺序表示的优点是:
(1) 无需为表示结点间的逻辑关系而增加额外的存储空间(因为逻辑上相邻的元素其存储的物理位置也是相邻的);(2) 可方便地随机存取表中的任一元素。
由上面的讨论可知, 线性表顺序表示的缺点:
(1) 插入或删除运算不方便, 除表尾的位置外,在表的其它位置上进行插入或删除操作都必须移动大量的结点,其效率较低;. (2) 由于顺序表要求占用连续的存储空间,存储分配只能预先进行静态分配,因此当表长变化较大时, 难以确定合适的存储规模。
所以在顺序存储之外,我们可以引入链式存储结构并且实现,链式存储会弥补顺序存储的不足,解决了顺序存储的诸多问题,但其本身也因为较为复杂有一定的局限性,需要好好学习,熟练使用。
转载:https://blog.csdn.net/qq_43656233/article/details/100807938