线性结构的特点是:在数据元素的非空有限集中,存在一个唯一的被称作为第一个的数据元素,存在唯一的一个被称作最后一个的数据元素,除第一个外,集合中的每个数据元素均只有一个前驱,出最后一个外,集合中每个数据元素均只有一个后继。
关系采用顺序映像,形成顺序存储结构,称之为顺序表。
编译环境:CodeBlocks 使用语言:类C语言
初始定义的辅助定义:
#define OK 1
#define LIST_INIT_SIZE 100//初始容量
#define LISTINCREMENT 10 //空间增量
#define ERROR 0
#define FALSE 0
#define TRUE 1
#define NULL 0
#define OVERFLOW -1
typedef int status;
顺序表的存储结构定义:
typedef int ElemType; //假设线性表元素为整形
typedef struct SqList{
ElemType *elem; //存储元素首地址
int ListSize; //表容量大小
int length; //表中元素个数
}SqList;
初始化一个空的有序顺序表:
status InitList_Sq(SqList &L){
//初始化一个空的有序顺序表
L.elem=(ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType));
if(L.elem==NULL)
exit(OVERFLOW);
L.ListSize=LIST_INIT_SIZE; //初始化存储容量
L.length=0; //初始化表长为0,空表
return OK;
}
删除第i个元素并用e带回 i介于1与L.length之间.
status ListDelete_Sq(SqList &L,int i,ElemType &e){
//删除第i个元素并用e带回 i介于1与L.length之间
if(i<1||i>L.length) //异常处理
return ERROR;
if(!L.elem)
return OVERFLOW;
ElemType *p=&L.elem[i],*q=L.elem+L.length-1;
e=*(p-1);
while(p<=q) //从前往后逐个前移
*(p-1)=*p++;
L.length--;
return OK;
}
在顺序表的第i个位置插入e。
int ListInsert_Sq(SqList &L,int i,ElemType e){
//在顺序表的第i个位置插入e
if(i<1||i>L.length+1) //插入位置不合法
return ERROR;
if(L.length==L.ListSize){ //表满,增加存储容量
L.elem=(ElemType *)realloc(L.elem,(L.ListSize+LISTINCREMENT)*sizeof(ElemType));//如果表容量不够
if(!L.elem)
exit(OVERFLOW);
L.ListSize+=LISTINCREMENT;
}
ElemType *p=&L.elem[i-1],*q=L.elem+L.length-1;
while(q>=p) //插入位置元素右移
*(q+1)=*q--;
*p=e;
L.length++; //表加长
return OK;
}
输出顺序表:
void OutputElem(ElemType e)
{
printf("%d\n",e);
}
void ListPrint_Sq(SqList &L){
//依次输出L中的各个元素
if(L.length==0)
printf("空表");
else{
for(int i=0;i<L.length;++i)
OutputElem(L.elem[i]);
}
}
销毁表L:
status DestroyList_Sq(SqList &L){
//销毁表L
if(L.elem)
free(L.elem);
L.elem=NULL;
L.length=0;
L.ListSize=0;
return OK;
}
清空表:
status ClearList_Sq(SqList &L){
// 清空表L
L.length=0;
return OK;
}
用e带回i位置的元素,如果i不合法返回ERROR
status GetElem_Sq(SqList &L,int i,ElemType &e){
//用e带回i位置的元素,如果i不合法返回ERROR
if(i<1||i>L.length)
return ERROR;
e=L.elem[i-1];
return OK;
}
更新第i个位置元素为e i不合法返回ERROR.
status PutElem_Sq(SqList &L,int i,ElemType e){
//更新第i个位置元素为e i不合法返回ERROR
if(i<1||i>L.length)
return ERROR;
L.elem[i-1]=e;
return OK;
}
返回L中第一个与e满足关系compare()的位序,不存在则返回0.
status compare(ElemType e1,ElemType e2)
{
return e1==e2;
}
int LocateElem_Sq(SqList L,ElemType e,status (*compare)(ElemType,ElemType)){
//返回L中第一个与e满足关系compare()的位序,不存在则返回0
ElemType *p=L.elem,*q=L.elem+L.length-1;
while(p<=q){
if(compare(*p,e))
return p-L.elem+1;
p++;
}
return 0;
}
对L中每个元素执行函数visit().
status visit(ElemType &e){
e+=10;
return OK;
}
status ListTraverse_Sq(SqList &L,status (*visit)(ElemType &)){
//对L中每个元素执行函数visit()
ElemType *p=L.elem,*q=L.elem+L.length-1;
while(p<=q)
visit(*p++);
return OK;
}
判断L是否为空
bool ListEmpty_Sq(SqList &L){
//判断L是否为空
if(!L.length)
return TRUE;
return FALSE;
}
返回L的长度
int ListLength_Sq(SqList &L){
//返回L的长度
return L.length;
}
若cur_e是L中的元素且不是第一个,就返回他的前驱,否则pre_e未定义 操作失败.
status PriorElem_Sq(SqList &L,ElemType cur_e,ElemType & pre_e){
//若cur_e是L中的元素且不是第一个,就返回他的前驱,否则pre_e未定义 操作失败
int i=LocateElem_Sq(L,cur_e,compare);
if(i<=1)
return ERROR;
pre_e=L.elem[i-2];
return OK;
}
若cur_e是L中的元素且不是最后一个,就返回他的后驱,否则pre_e未定义 操作失败.
status NextElem_Sq(SqList &L,ElemType cur_e,ElemType & next_e){
//若cur_e是L中的元素且不是最后一个,就返回他的后驱,否则pre_e未定义 操作失败
int i=LocateElem_Sq(L,cur_e,compare);
if(i<1||i>L.length-1)
return ERROR;
next_e=L.elem[i];
return OK;
}
元素x插入递增顺序表L中,使得原表仍然有序
status ListInsert_Sorted(SqList &L,ElemType e){
//元素x插入递增顺序表L中,使得原表仍然有序
//从最后一个位置开始,只要它比待插入元素大就后移。条件不成立时,退出循环,将e
//插入当前位置即可。注意顺序表插入时表满的处理。
//只要是顺序表的插入操作就需要判断是否表满,对于链表无此要求。
if(L.length>=L.ListSize) //表满,增加存储容量
{
L.elem=(ElemType*)realloc(L.elem,(L.length+LISTINCREMENT)*sizeof(ElemType));
if(!L.elem)
exit(OVERFLOW);
L.ListSize += LISTINCREMENT;
}
//下面从最后一个元素开始,只要大于e就后移,最后插入当前位置后。
ElemType *q=L.elem+L.length-1;
while(q>=L.elem&&*q>e){
*(q+1)=*q;
q--;
}
*(q+1)=e;
L.length++; //表长加1
return OK;
}
表的倒序。
status ListInverse(SqList &L){
//顺序表就地逆置
//分别设两个指针p与q指向第一个与最后一个元素,只要p<q,
//*p与*q互换,之后++p,--q
ElemType e,*p=L.elem,*q=L.elem+L.length-1;
while(p<q){
e=*p;
*p=*q;
*q=e;
p++;
q--;
}
return OK;
}