基本操作
Status InitList(SqList *L)
操作结果:构造一个空线性表
void DestroyList(SqList *L)
初始条件:线性表L存在
操作结果:销毁线性表L
void ClearList(SqList *L)
初始条件:线性表L存在
操作结果:将线性表L重置为空表
int IsEmpty(SqList L)
初始条件:线性表L存在
操作结果:若线性表L为空表,返回TRUE,否则返回FALSE
int ListLength(SqList L)
初始条件:线性表L存在
操作结果:返回线性表L中的数据元素个数
int GetElem(SqList L, int i, ElemType *e)
初始条件:线性表L存在 1<=i<=ListLength(L)
操作结果:用e返回线性表种第i个数据元素的值
int LocateElem(SqList L,ElemType e)
初始条件:线性表L已经存在,compare()是数据元素判定的函数
操作结果:返回L种第一个满足compare()的数据元素的位序。若这样的元素不存在则返回0
Status PriorElem(SqList L, ElemType cur_e, ElemType *Pre_e)
初始条件:线性表L存在
操作结果:若cur_e是L的数据元素,且不是第一个,用Pre_e返回他的前驱,否则操作失败
Status NextElem(SqList L, ElemType cur_e, ElemType *Pre_e)
初始条件:线性表L存在
操作结果:若cur_e是L的数据元素,且不是最后一个,用Pre_e返回他的前驱,否则操作失败
Status ListInset(SqList *L, int i,ElemType e)
初始条件:线性表L存在 1<=i<=l.length+1
操作结果:在L的第i个位置之前插入新的数据元素e,L的长度加一
Status ListDelete(SqList *L,int i)
初始条件:线性表L存在 1<=i<=l.length
操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减一
Status ListTeaverse(SqList L)
初始条件:线性表L存在
操作结果:在控制台中打印线性表中的所有元素
代码实现
#include <stdio.h>
#define TURE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define MAXSIZE 10
//status是函数的类型,其值是函数结果状态代码
typedef int Status;
typedef char ElemType;
//定义数组
typedef struct{
ElemType *data;
int length;
}SqList;
//线性表的初始化 (数组地址)
Status InitList(SqList *L){
*L->data = (ElemType*)malloc(sizeof(ElemType)*MAXSIZE);
// sizeof(x)计算x的长度 malloc(m)开辟m字节的地址空间,并返回这段空间的地址
L->length = 0;
if (!(L->data))
exit(OVERFLOW);
return OK;
}
//销毁线性表(数组地址)
void DestroyList(SqList *L){
if (L->data) free(*L); //free(p) 释放指针p所指变量的存储空间,即彻底删除一个变量
}
//清空线性表(数组地址)
void ClearList(SqList *L){
L->length = 0;
}
//判断线性表是否为空(数组)
int IsEmpty(SqList L){
if (L.length == 0)
return 1;
else
return 0;
}
//返回线性表元素个数
int ListLength(SqList L){
return L.length;
}
//顺序表的取值(数组,取值位置,值地址)
int GetElem(SqList L, int i, ElemType *e){
if (i<1 || i>L.length) return ERROR;
*e = L.data[i - 1];
return OK;
}
//顺序表的查找(数组,需查找的值)
int LocateElem(SqList L,ElemType e){
for (int i = 0; i < L.length; i++)
if (L.data[i] == e)
return i + 1;
return 0;
}
//返回元素的前驱
Status PriorElem(SqList L, ElemType cur_e, ElemType *Pre_e){
for (int i = 0; i <L.length; i++)
{
if (L.data[i] == cur_e)
if (i != 0){
*Pre_e = L.data[i - 1];
return OK;
}
}
return ERROR;
}
//返回元素的后继
Status NextElem(SqList L, ElemType cur_e, ElemType *Pre_e){
for (int i = 0; i <L.length; i++)
{
if (L.data[i] == cur_e)
if (i != L.length-1){
*Pre_e = L.data[i + 1];
return OK;
}
}
return ERROR;
}
//顺序表的插入
Status ListInset(SqList *L, int i,ElemType e){
if (i<1 || i> (*L).length +1)
return ERROR;
if (L->length == MAXSIZE)
return ERROR;
for (int j = L->length; j >= i-1; j--)
L->data[j + 1] = L->data[j];
L->data[i - 1] = e;
L->length++;
return OK;
}
//顺序表的删除
Status ListDelete(SqList *L,int i){
if (i<1 || i>L->length)
return ERROR;
for (int j = i; j <= L->length; j++)
L->data[j-1] = L->data[j];
L->length--;
return OK;
}
//访问每一个元素
Status ListTeaverse(SqList L){
if (L.length == 0)
return ERROR;
printf("[");
for (int i = 0; i < L.length; i++){
if (i!=L.length-1)
printf("%c,", L.data[i]);
else
printf("%c", L.data[i]);
}printf("]");
return OK;
}
int main(void){
SqList L;
InitList(&L);
//给线性表L传入两个值
ListInset(&L, 1, 'H');
ListInset(&L, 2, 'T');
ListTeaverse(L);
ElemType e='1';
GetElem(L, 2, &e);
printf("线性表第二个元素为%c\n", e);
PriorElem(L, 'T', &e);
printf("字母T的前驱为%c\n", e);
NextElem(L, 'H', &e);
printf("字母H的后继为%c\n", e);
//判断线性表是否为空表
ListDelete(&L, 1);
printf("字母T在元素中的位置是%d\n", LocateElem(L, 'T'));
if (IsEmpty(L))
printf("线性表是空表");
else
printf("线性表不是空表");
//情况线性表内存
DestroyList(&L);
}
时间复杂度
1.查找、插入、删除算法的平均时间复杂度为O(n)
2.顺序表操作算法的空间复杂度为 S(n)=O(1)
顺序表的优缺点
优点
1.存储密度大(节点所占存储量/节点结构所占存储量)
2.可以随机存取表中任一元素
缺点
1.在插入、删除某一元素时,需要移动大量元素
2.浪费存储空间
3.属于静态存储形式,数据元素个数不能自由扩充