文章目录
线性表的顺序表示与实现2
线性表通过数组存储:
线性表L:
SqList L;
引用成员:L.elem L.length
指针形式
SqList *L;
L->elem L->length
补充:操作算法中用到的预定义常量和类型
//函数状态代码
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASILB -1
#define OVERFLOW -2
//Status 是函数的类型,其值是函数结果状态代码
typedef int Status;
typedef char ElemType;
infeasible:adj. 不可实行的
顺序表基本操作的实现
1、线性表L的初始化
Status InitList_Sq(SqList &L){ //构造一个空的顺序表L
L.elem = new ElemType[MAXSIZE]; //为顺序表分配空间 L.elem是数组首地址
if(!L.elem) exit(OVERFLOW); //存储分配失败 !有内容-->假 !无内容-->真,分配失败退出
L.length=0; //空表长度为0
return OK;
}
2、销毁线性表
void DestroyList(SqList &L){
if(L.elem) delete L.elem;
}
L.elem有内容 --> 销毁L.elem
L.elem无内容 --> 无操作
3、清空线性表
void ClearList(SqList &L){
L.length=0; ?为什么不把数组里的元素置为0
}
4、求线性表的长度
int GetLength(SqList L){
return (L.length);
}
5、判断线性表L是否为空
int IsEmpty(SqList L){
if (L.length==0) return 1;
else return 0;
}
6、取值
取线性表中第i个元素的值 —> 线性表随机存取的特性
int GetElem(SqList L, int i, ElemType &e){
if (i<1 || i>L.length) return ERROR; //判断
e=L.elem[i-1]; //数组第i-1号 存储着第i个数据
return OK;
}
算法固定执行1次/10000次 复杂度O(1)
算法执行的次数固定不变 常量阶,复杂度O(1)
7、查找
LocateElem(L, e):在线性表L中查找与指定值e相同的数据元素的位置,若成功,返回该元素在表中是第几个元素,否则返回0(按值查找)
分析:从表的一端开始,逐个查找
int LocatedElem(SqList L, ElemType e){
for(i=0; i<L.length; i++) //i是数组序号
if(L.elem[i]==e) return i+1; //i+1是第几个
return 0;
}
return:返回结果 并结束当前的函数
时间复杂度:if(L.elem[i]==e)为基本语句 n=L.length
平均查找长度(ASL Average Search Length) =(1+2+3+···+n-1+n)/n = (n+1)/2 (查找次数的期望值)
平均时间复杂度:O(n)
8、插入
插入元素后的线性表必须保证连续的特性,例如,插最后一个元素时必须紧跟原线性表的末尾元素
插入位置思想: 将元素f、a依次后移,再将g放入 length加1
算法思想:
①判断插入位置i是否合法
②判断顺序表的存储空间是否已满,若已满返回ERROR
③将第n至第i位的元素依次向后移动一个位置,空出第i个位置
④将元素e放入第i个位置
⑤表长加1,插入成功返回OK
Status ListInsert_Sq(SqList &L, int i, ElemType e){
if(i<1 || i>L.length+1) return ERROR; //判断插入位置i是否合法
if(L.length == MAXSIZE) return ERROR; //判断顺序表的存储空间是否已满
for(j=L.length-1; j>=i-1; j--){
L.elem[j+1] = L.elem[j]; //插入元素及之后的元素依次后移
}
L.elem[i-1] = e; //将元素e放入第i个位置
L.length++; //表长增1
return OK;
}
算法分析:
可插入的位置有(n+1)个 n:线性表中元素个数
插入第(n+1)个位置:移动0次
插入第n个位置:移动1次
插入第(n-1)个位置:移动2次
···
插入第2个位置:移动(n-1)次
插入第1个位置:移动n次
插入位置 + 移动次数 = n + 1
平均移动次数:n/2(每一种出现的可能性是1/n+1)
平均时间复杂度:O(n)
9、删除
算法思想:
①判断删除位置i 是否合法(合发值为1≤i≤n)
②将第i+1至第n位的元素依次向前移动一个位置
③表长减1,删除成功返回OK
Status ListDelete Sq(SqList &L, int i){
if(i<1 || i>L.length) return ERROR; //判断删除位置i是否合法
for(j=i; j<=L.length-1; j++){ //被删除元素之后的元素前移
L.elem[j-1]=L.elem[j];
}
L.Length--; //表长减1
return OK;
}
算法分析:
删除位置i | 第1个 | 第2个 | ··· | 第(n-2)个 | 第(n-1)个 | 第n个 |
---|---|---|---|---|---|---|
移动次数 n-i | n-1 | n-2 | ··· | 2 | 1 | 0 |
平均移动次数:(n-1)/2(每一种出现的可能性是1/n)
平均时间复杂度:O(n)
线性表小结
算法分析:
- 时间复杂度:查找、插入、删除算法的平均时间复杂度为O(n)
- 空间复杂度:顺序表操作算法的空间复杂度S(n)=O(1)(没有占用辅助空间)
优缺点:
优点:
- 存储密度大
- 可以随机存取表中任一元素
缺点:
- 在插入、删除某一元素时,需要移动大量元素
- 浪费存储空间
- 属于静态存储结构,数据元素的个数不能自由扩充