学习严蔚敏老师《数据结构(C语言版)》,关于顺序表的基本操作:
1.线性表的动态分配顺序存储结构
2.初始化 InitList_Sq【2.3】
3.插入 ListInsert_Sq【2.4】
4.删除 ListDelete_Sq【2.5】
5.遍历顺序表 ListTraverse_Sq
6.置为空表 ClearList_Sq
7.销毁线性表 DestroyList_Sq
8.判断是否为空表 ListEmpty_Sq
9.L中的数据元素个数 ListLength_Sq
10.返回L中第i个元素的值 GetElem_Sq
11.返回L中第一个与e满足关系compare()的数据元素的位序 LocateElem_Sq【2.6】
12.找前驱 PriorElem_Sq
13.找后继 NextElem_Sq
#include<stdio.h>
#include<stdlib.h>
typedef int Status; //状态码识别类型
typedef int ElemType;
#define LIST_INIT_SIZE 100 //顺序表存储空间的初始分配量
#define LISTINCREMENT 10 //顺序表存储空间的分配增量
#define OVERFLOW -2 //堆栈上溢
#define UNDERFLOW -3 //堆栈下溢
//△01 线性表的动态分配顺序存储结构
typedef struct{
ElemType *elem;//存储空间基地址
int length; //当前长度
int listsize; //当前分配的存储空间大小(以sizeof(ElemType)为单位)
}SqList;
//△02初始化,构造一个空的线性表L
Status InitList_Sq(SqList &L){
L.elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));
if(!L.elem){//存储分配失败, ☆exit结束进程,将OVERFLOW的值返回给操作系统
exit(OVERFLOW);
}
L.length=0;
L.listsize=LIST_INIT_SIZE;
return 1;
}
//△03在第i个位置(L.elem[i-1])插入值为x的数据元素
Status ListInsert_Sq(SqList &L,int i,ElemType e){
if(i<1||i>L.length+1){
return 0;
}
ElemType *newbase;
ElemType *p,*q;
//当前存储空间已满,增加分配
if(L.length>=L.listsize){
newbase=(ElemType*)realloc(L.elem,
(L.listsize+LISTINCREMENT)*sizeof(ElemType));
if(!newbase){
exit(OVERFLOW);
}
L.elem=newbase;//新基址
L.listsize+=LISTINCREMENT;//增加存储容量
}
q=&(L.elem[i-1]);//q为插入位置
for(p=&(L.elem[L.length-1]);p>=q;p--){
*(p+1)=*p; //右移
}
*q=e;
L.length++;
return 1;
}
//△04删除顺序表L中第i个元素,并用e返回其值
Status ListDelete_Sq(SqList &L,int i,ElemType &e){
if(i<1||i>L.length){
return 0;
}
ElemType *p,*q;
p=&(L.elem[i-1]);
e=*p;
q=L.elem+L.length-1;//q为表尾元素的位置
for(p;p<=q;p++){
*p=*(p+1);
}
L.length--;
return 1;
}
void PrintElem(ElemType e){
printf("%d ", e);
}
//△05遍历顺序表
Status ListTraverse_Sq(SqList L,void (visit)(ElemType)){
for(int i=0;i<L.length;i++){
visit(L.elem[i]);
}
printf("\n");
return 1;
}
//△06置为空表
void ClearList_Sq(SqList &L){
L.length = 0;
}
//△07销毁线性表
void DestroyList_Sq(SqList &L){
free(L.elem);
L.elem = NULL; //释放内存后置空指针
L.length = 0;
L.listsize = 0;
}
//△08判断是否为空
Status ListEmpty_Sq(SqList L){
return L.length==0?true:false;
}
//△09顺序表L中的元素个数
int ListLength_Sq(SqList L){
return L.length;
}
//△10返回第i个元素的值
Status GetElem_Sq(SqList L,int i,ElemType *e){
if(i<1||i>L.length){
return 0;
}
*e=L.elem[i-1];
return 1;
}
Status CmpGreater(ElemType e, ElemType data){
return data>e?true:false;
}
//△11 返回L中第一个与e满足关系compare()的数据元素的位序
int LocateElem_Sq(SqList L, ElemType e, Status (Compare)(ElemType,ElemType)){
int i = 1; //i的初值为第一个元素的位序
ElemType *p=L.elem; //p的初值为第一个元素的存储位置
while(i<=L.length&&!Compare(e,*p++)){
i++;
}
if(i<=L.length){
return i;
}else{
return 0;
}
}
//△12 找前驱
Status PriorElem_Sq(SqList L, ElemType cur_e, ElemType *pre_e){
int i = 1;
//第一个结点无前驱
if(L.elem[0]!=cur_e){
while(i<L.length&&L.elem[i]!=cur_e){
i++;
}
if(i<L.length){
*pre_e=L.elem[i-1];
return 1;
}
}
return 0;
}
//△13 找后继
Status NextElem_Sq(SqList L, ElemType cur_e, ElemType *next_e){
int i=0;
while(i<L.length && L.elem[i]!=cur_e){
i++;
}
//最后一个结点无后继
if(i<L.length-1){
*next_e=L.elem[i+1];
return 1;
}
return 0;
}
int main(){
SqList L;
ElemType e;
int i;
printf("————————————————————————————△02初始化为空表\n");
InitList_Sq(L);//初始化
printf("————————————————————————————△08判空\n");
if(ListEmpty_Sq(L)){//判空
printf("L为空表\n");
} else{
printf("L为非空表\n");
}
printf("————————————————————————————△03插入\n");
for(int i=1;i<=6;i++){
ListInsert_Sq(L,i,i-1);//在第i个位置插入值为i-1的数据元素
}
ListTraverse_Sq(L,PrintElem);//遍历
printf("————————————————————————————△04删除 & △09元素个数\n");
printf("当前L中的元素个数为:%d\n",ListLength_Sq(L));
ListDelete_Sq(L,2,e);//删除第2个元素
ListTraverse_Sq(L,PrintElem);
printf("此时L中的元素个数为:%d\n",ListLength_Sq(L));
printf("————————————————————————————△10位序上的元素值\n");
GetElem_Sq(L,2,&e);
printf("此时L中第2个数据元素为:%d\n",e);
printf("————————————————————————————△11满足关系的位序\n");
printf("L中第一个元素值大于2的元素所在的位置是%d\n",LocateElem_Sq(L,2,CmpGreater));
printf("————————————————————————————△12前驱 & △13后继\n");
PriorElem_Sq(L,3,&e);
printf("元素3的前驱为:%d\n",e);
NextElem_Sq(L,3,&e);
printf("元素3的后继为:%d\n",e);
printf("————————————————————————————△06置空\n");
printf("清空操作前:");
ListEmpty_Sq(L) ? printf(" L为空表!\n") : printf(" L不为空表!\n");
ClearList_Sq(L);//置为空表
printf("清空操作后:");
ListEmpty_Sq(L) ? printf(" L为空表!\n") : printf(" L不为空表!\n");
printf("————————————————————————————△07销毁\n");
printf("销毁L前:");
L.elem ? printf("L存在!\n") : printf("L不存在!\n");
DestroyList_Sq(L);//销毁线性表
printf("销毁L后:");
L.elem ? printf("L存在!\n") : printf("L不存在!\n");
return 0;
}