线性表
线性表:由一个或多个元素组成的有序列表
线性表是一个有序的列表,这个列表中的元素像线一样按照一定的次序排号的列表
顺序存储结构
线性表的顺序储存结构,指的是用一段地址连续的储存单元依次储存线性表的数据元素
线性表是一块连续的内存地址,所以一般用一维数组来实现线性表,线性表包含了一个一维数组来储存数据,以及含有该线性表当前的数据长度,线性表的起始下标设定为1。所以线性表是一个结构体。
由于线性表是一个一维数组形成,并且下标从1开始,所以下标的计算方法
顺序存储结构的功能
默认参数
#define N 200
#define ERROR 0;
#define TRUE 1;
#define OK 1;
#define false 0;
typedef int elemtype;
typedef struct
{
elemtype data[N];
elemtype length;
}sqlist;
查询元素
查询思路:
- 查询位置错误,抛出异常
int GetElem(sqlist l, int i, int *e) // 查找列表l中的第i个位置的元素并且返回给e
{
if (i <= 0 || i > l.length || l.length == 0)
{
return ERROR;
}
*e = l.data[i - 1];
return OK;
}
元素插入
插入思路
- 插入位置错误或不存在,抛出异常
- 如果线性表的长度大于等于数组的长度,则抛出异常或者动态增容
- 如果插入的位置不是最后一个位置,那么插入位置后面的元素往后移动一位
- 将元素插入到位置i
- 表长长度增加1
int ListInsert(sqlist *l, int i, int e) // 向列表l中第i位置插入一个元素e
{
if (i > l->length + 1 || i <= 0)
return ERROR;
if (i <= l->length) // 判断是否插入在列表末尾
{
for (int k = l->length - 1; k >= i - 1; k--)
{
l->data[k + 1] = l->data[k];
}
l->data[i - 1] = e;
l->length++;
return OK;
}
}
从中可以看出,最好的情况就是插入的位置在最后一个,这时候时间复杂度为O(1)。但是如果这个时候插入的位置是第一位,这个被称之为最坏情况,他的时间复杂度是O(length - 1 )。所以我们要的是平均的情况这个时候时间复杂度为O((length - 1) / 2)
元素删除
- 如果删除位置不存在,或者位置错误则抛出异常
- 将删除的元素返回
- 如果删除的位置不是最后一个,则删除位置后面元素全部往前移动一位
- 长度减1
int ListDelete(sqlist *l, int i, int *e) // 删除列表L中i的位置并且将删除的位置的值返回给e
{
if (i < 1 || i > l->length || l->length == 0)
{
return ERROR;
}
*e = l->data[i - 1];
if (i < l->length - 1) // 判断删除的是不是最后一个
{
for (int k = i - 1; k < l->length + 1; k++)
{
l->data[k] = l->data[k + 1];
}
}
l->length--;
return OK;
}
清空线性表内容&获取长度
int ClearList(sqlist *l) // 清空线性表
{
*l->data = {};
l->length = 0;
return OK;
}
int Listlength(sqlist l) // 获取线性表的长度
{
return l.length;
}
线性表的优劣
优点:
-
无需为表示表中元素之间的逻辑关系而增加额外的存储空间
-
可以快速地存取表中任一位置的元素
缺点:
- 插入删除操作需要移动大量元素
- 当线性表长度变化较大时,难以确定存储空间的容量
- 造成存储空间的碎片