目录
顺序表
线性表的顺序表示又称顺序存储结构或 顺序映像。
-
把逻辑上相邻的数据元素储存在物理位置上也相邻的存储单元中的存储结构。
操作算法中用到的预定义常量和类型
1.函数结果状态
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
2.Status 是函数的类型,其值是函数结构状态
typedef int(或是其他类型) Status; (通常指返回的状态的类型)
typedef char(或是其他类型) ElemType; (通常指返回的元素的类型)
顺序表(Sequence List)定义
-
静态定义
#define MAXSIZE 100 typedef struct { ElemType elem[MAXSIZE]; int length; } SqList;
-
动态定义
#define MAXSIZE 100 typedef struct { ElemType *elem; int length; } SqList; L.elem=(ElemType*)malloc(sizeof(ElemType)*MAXSIZE);
线性表L的初始化
Status InitList_Sq(SqList &L) { //构造一个空的顺序表L(引用类型是c++的,c可以用二级指针实现)
L.elem = new ElemType[MAXSIZE] //为顺序表分配空间(c++语法,如果是c则用malloc)
if(!l.elem) exit(OVERFLOW); //存储分配失败
L.length = 0; //空表长度为0
return OK;
}
线性表L的销毁
void DestroyList(SqList &L) {
if(L.elem) delete L.elem; //释放空间,c则是free(L.elem)
}
线性表L的清空
-
和销毁不一样,销毁是把整个顺序表的内存空间释放掉了
void ClearList(SqList &L) {
L.length = 0; //将线性表长度设置为0
}
线性表L的长度获取
int GetLength(SqList L) {
return (L.length);
}
判断线性表是否为空
int isEmpty(SqList L) {
if(L.length == 0) return 1;
else return 0;
}
顺序表的取值
-
根据位置 i 获取相应位置数据元素的内容
-
时间复杂度为O(1)
int GetElem(SqList L, int i, ElemType &e) {
if(i<1 || i>L.length) return ERROR;
//判断i值是否合理,不合理则返回ERROR
e = L.elem[i-1]; //第i-1的单元储存着第i个数据
return OK;
}
顺序表的查找
-
在线性表L中查找与指定值e相同的数据元素的位置
-
从表的一端开始,逐个进行 记录的关键字和给定值的比较。找到,返回该元素的位置序号,未找到,返回0。
-
时间复杂度为O(n)
int LocateElem(SqList L, ElemType e) {
//在线性表L中查找值为e的元素,返回其序号(是第几个元素)
for(i=0;i<L.length;i++)
if(L.elem[i] == e) return i+1;//查找成功,返回序号
return 0;//查找失败,返回0
}
顺序表的插入
三种情况:
-
插入位置在最后
-
插入位置在中间
-
插入位置在最前面
算法思想
-
判断插入位置 i 是否合法。
-
判断顺序表的存储空间是否已满,若满则返回ERROR。
-
将第n至第 i 位的元素依次向后移动一个位置,空出第 i 个位置
-
将要插入的新元素放入第 i 个位置
-
表长+1,插入成功返回OK。
-
时间复杂度为O(n)
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;
}
顺序表的删除
三种情况:
-
删除位置在最后
-
删除位置在中间
-
删除位置在最前面
算法思想:
-
判断删除位置 i 是否合法(合法值为1<=i<=n)。
-
*将欲删除的元素保留在e中。(也可以不保留)
-
将第i+1至第n位的元素依次向前移动一个位置。
-
表长减1,删除成功返回OK。
-
时间复杂度为O(n)。
Status ListDelete_Sq(SqList &L, int i) {
if(i<1 || i>L.length) return ERROR; //i值不合法
for(j = i; j<= L.length-1)
L.elem[j-1] = L.elem[j]; //被删除元素之后的元素前移
L.length--; //表长减一
return OK;
}
总结
顺序表(线性表的顺序存储结构)的特点
-
利用数据元素的存储位置表示线性表中相邻数据元素之间的前后关系,即线性表的逻辑结构与存储结构一致。
-
在访问线性表时,可以快速地计算出任何一个数据元素的存储地址。因此可以粗略的认为,访问每个元素所花时间相等。
-
这种存取元素的方法被称为 随机存取法
-
查找、插入、删除算法的平均时间复杂度为T(n) = O(n)。
-
因为没有占用额外辅助空间,所以空间复杂度S(n) = O(1)。
优点:
-
存储密度大(结点本身所占存储量/结点结构所占存储量)。
-
可以随机存取表中任一元素。
缺点:
-
在插入、删除某一元素时,需要移动大量元素。
-
浪费存储空间。
-
属于静态存储形式,数据元素的个数不能自由扩充。