数据结构之线性表(一):顺序表的实现和应用
一.顺序表基本操作实现(所有代码均在Embarcadero DevC++6.0和VSCode 2021上编译运行通过):
#include<stdio.h>
#include<stdlib.h>
#define Elemtype int
#define LIST_INIT_SIZE 100 //顺序表总初始分配量
#define LISTINCREMENT 10 //顺序表间隔量
#define OVERFLOW -1
#define STACK_INIT_SIZE 10
#define STACKINCREMENT 2
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
//int InitList(Sqlist L); //构造一个空的线性表L
//ListEmpty(L); //判断线性表L是否是空表,若是,则返回TRUE,否则返回FALSE
//ListLength(L); //返回线性表L的长度
//GetElem(L,i,&e) ; //用e返回线性表L的第i个数据元素的值
//LocateElem(L,e,compare());//在线性表L中查找第一个和元素e满足compare关系//的元素,若找到则返回其位序;否则返回0
//PriorElem(L,e, &pre_e); //用pre_e返回线性表L中元素e的直接前驱
//NextElem(L, e, &next_e); //用next_e返回线性表L中元素e的直接后继
//ListInsert(&L,i,e) ; //将数据元素e插入到线性表L的第i个数据元素之前
//ListDelete(&L,i,&e); //删除线性表L的第i个数据元素,并将其值用e返回
//ListTraverse(L,visit()); //依次对线性表L中的每个元素调用visit进行访问
//ClearList(&L); //重置线性表L为空表
//DestroyList(&L); //销毁线性表L,可能的话释放其空间
typedef int Status;
typedef struct
{
Elemtype *elem; //存储空间基地址
int length; //顺序表当前长度
int listsize; //顺序表总存储空间长度
}Sqlist;
int LocateElem(Sqlist L,Elemtype e)//在线性表L中查找第一个和元素e满足compare关系//的元素,若找到则返回其位序;否则返回0
{
int i;
for(int i=1;i<=L.length && L.elem[i-1]!=e ;i++);
if(L.length<i)
return 0;
else
return i;
}
Elemtype PriorElem(Sqlist L,Elemtype e, Elemtype &pre_e) //用pre_e返回线性表L中元素e的直接前驱
{
int j;
j = LocateElem(L, e); //定位函数获取元素e位置:第j个
if(L.elem[0]==e) //如果已经是首元素
return ERROR;
else
return L.elem[j-1-1]; //前驱元素正确位置
}
Elemtype NextElem(Sqlist L, Elemtype e, Elemtype &next_e) //用next_e返回线性表L中元素e的直接后继
{
int j;
j = LocateElem(L, e); //定位函数获取元素e位置:第j个
if(L.elem[L.length-1]==e) //如果已经是尾元素,无后继
return ERROR;
else
return L.elem[j-1+1]; //前驱元素正确位置
}
Status ListDelete(Sqlist &L,int i,Elemtype &e) //删除线性表L的第i个数据元素,并将其值用e返回
{
if(i<0||i>L.length)
return ERROR;
e = L.elem[i-1];
for(int *p= &L.elem[i-1];p<=&(L.elem[L.length-1-1]);p++)
{
*(p) = *(p+1);
}
L.length--;
return OK;
}
void ClearList(Sqlist &L) //重置线性表L为空表
{
L.length = 0;
}
Status ListInsert(Sqlist &L,int i,Elemtype e) //将数据元素e插入到线性表L的第i个数据元素之前
{
if(i<=0||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;
if(L.length==0)
p = L.elem;
else
{
p = L.elem+L.length-1;
for(int *temp = L.elem+i-1 ;p>=temp;p--) //倒着把i后面到n的元素依次后移一位
*(p+1) = *p;
}
L.elem[i-1] = e; //i的位置放e
L.length++;
return OK;
}
Status ListTraverse(Sqlist L,Status (*visit)(Elemtype )) //依次对线性表L中的每个元素调用visit进行访问
{
for(int *p = L.elem; p<L.elem+L.length;p++ )
{
if(!visit(*p))
return ERROR;
}
return OK;
}
Status print(Elemtype e) //访问函数
{
printf("%d->", e);
return OK;
}
Status InitList(Sqlist &L) //构造一个空的线性表L
{
L.elem=(Elemtype*)malloc(LIST_INIT_SIZE*sizeof(Elemtype));//为init_size个存储申请内存空间
if(!L.elem)
exit(OVERFLOW); //判断是否为空
L.length = 0; //初始化顺序表当前长度为0
L.listsize = LIST_INIT_SIZE;//初始化总空间长度为100个
return OK;//初始化无误,函数返回OK(1)
}
Status ListEmpty(Sqlist L) //判空函数
{
if(!L.length)
return TRUE;
else
return FALSE;
}
int ListLength(Sqlist L) //返回线性表L的长度
{
return L.length;
}
Elemtype GetElem(Sqlist L,int i,Elemtype &e) //用e返回线性表L的第i个数据元素的值
{
if(i<0 || i>L.length )
return ERROR;
e = L.elem[i-1];
return OK;
}
void DestroyList(Sqlist &L) //销毁线性表L,可能的话释放其空间
{
if(L.elem) free(L.elem); //该段空间被释放,重新成为可用空间
L.elem = NULL;
}
int main()
{
int a;
Elemtype e;
Sqlist L;
a = InitList(L);
printf("%d\n",a);
for(int i=1;i<=10;i++)
{
ListInsert(L,i,i);
}
ListDelete(L,5,e);
if(ListTraverse(L,print))
printf("OK\n");
else
printf("ERROR\n");
return 0;
}