这几天,学习了数据结构的线性表,今天打算总结一下相关内容!
因为线性表的顺序存储结构是一种随机存取的存储结构,同时线性表的长度可变,且所需最大存储空间随问题不同而不同,则在C语言中,用动态分配的一维数组来实现。
下面是线性表的动态分配顺序存储结构:
typedef struct
{
ElemType *elem; // 存储空间基址
int length; // 当前长度
int listsize; // 当前分配的存储容量(以sizeof(ElemType)为单位)
} SqList;
该程序采用菜单和结构体数组,这样方便测试每个功能的实现。同时将类C代码转换成C语言源代码,并执行程序。
功能包括:初始化,创建,显示,插入,删除,查找。
/**
2016/09/28
1.Alt+F8:格式化代码块
*/
//预编译命令
#include<stdio.h>
#include<stdlib.h>
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define LIST_INIT_SIZE 10 //表存储空间的初始分配量
#define LISTINCREMENT 2 // 线性表存储空间的分配增量
//数据结构
typedef int Status;
typedef int ElemType;
typedef struct
{
ElemType *elem; // 存储空间基址
int length; // 当前长度
int listsize; // 当前分配的存储容量(以sizeof(ElemType)为单位)
} SqList;
//函数声明
int menu_select();
Status InitList_Sq(SqList &L);
Status CreatList_Sq(SqList &L,int n);
void PrintList_Sq(SqList L);
Status ListInsert_Sq(SqList &L, int i, ElemType e);
Status ListDelete_Sq(SqList &L, int i, ElemType &e);
int LocateElem_Sq(SqList L, ElemType e, Status (*compare)(ElemType, ElemType));
Status equal(ElemType x, ElemType y);
// Status greater(ElemType x, ElemType y);
// Status less(ElemType x, ElemType y);
//主函数
void main()
{
SqList L;
Status s;
int n,i;
ElemType e;
for(;;)
{
switch(menu_select())
{
case 1:
printf("初始化\n");
s=InitList_Sq(L);
if(s)
printf("初始化成功\n");
else
printf("初始化失败\n");
break;
case 2:
printf("请输入线性表元素的个数:");
scanf("%d",&n);
s=CreatList_Sq(L,n);
if(s)
printf("创建成功\n");
else
printf("创建失败\n");
break;
case 3:
printf("输出顺序表\n");
PrintList_Sq(L);
break;
case 4:
printf("请输入插入的位序和新元素的值(以空格分开):");
scanf("%d%d",&i,&e);
s=ListInsert_Sq(L,i,e);
if(s)
printf("插入成功\n");
else
printf("插入失败\n");
break;
case 5:
printf("请输入删除的位序:");
scanf("%d",&i);
s=ListDelete_Sq(L,i,e);
if(s)
printf("删除了元素%d成功\n",e);
else
printf("删除失败\n");
break;
case 6:printf("请输入查找的元素的值:");
scanf("%d",&e);
i=LocateElem_Sq(L, e, equal); //指向函数类型的指针作形参,实参用同类型的函数名equal
if(i)
printf("%d的逻辑位序是%d\n",e,i);
else
printf("查找失败\n");
break;
case 0:
printf("程序结束,谢谢使用!\n\n");
exit(0);
}
}
}
//菜单函数
int menu_select()
{
int sn;
printf("\n显示菜单\n");
printf("1.初始化\n");
printf("2.创建\n");
printf("3.显示\n");
printf("4.插入\n");
printf("5.删除\n");
printf("6.查找\n");
printf("0.退出\n");
printf("输入 0-7:");
for(;;)
{
scanf("%d",&sn);
if(sn<0||sn>6)
printf("\n输入错误,重选0-6:");
else
break;
}
return sn;
}
//初始化函数
Status InitList_Sq(SqList &L)
{
L.elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));
if(!L.elem)
exit(OVERFLOW);
L.length=0;
L.listsize=LIST_INIT_SIZE;
return OK;
}
//创建线性表
Status CreatList_Sq(SqList &L,int n)
{
int i;
if(n>L.listsize)
return ERROR;
for(i=1;i<=n;i++)
{
scanf("%d",&L.elem[i-1]);
}
L.length=n;
return OK;
}
//输出函数
void PrintList_Sq(SqList L)
{
int i;
for(i=1;i<=L.length;i++)
{
printf("%d\t",L.elem[i-1]);
}
printf("\n");
}
//插入函数定义
Status ListInsert_Sq(SqList &L, int i, ElemType e)
{
ElemType *newbase,*q,*p; //教材用的伪码,变量的声明补出来
if(i<1||i>L.length+1)
return ERROR;
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];
for(p=&L.elem[L.length-1];p>=q;p--)
{
*(p+1)=*p;
}
*q=e;
L.length++;
return OK;
}
//删除函数定义
Status ListDelete_Sq(SqList &L, int i, ElemType &e)
{
ElemType *q,*p; //教材用的伪码,变量的声明补出来
if((i<1)||(i>L.length))
return ERROR;
p = &(L.elem[i-1]);
e = *p;
q = L.elem+L.length-1;
for(++p;p<=q;++p)
*(p-1)=*p;
--L.length;
return OK;
}
//查找函数定义
int LocateElem_Sq(SqList L, ElemType e, Status (*compare)(ElemType, ElemType))
//指向函数类型的指针作形参
{
ElemType *p;
int i;
i = 1;
p = L.elem;
while(i<=L.length&&!(*compare)(*p++, e))
++i;
if(i<=L.length)
return i;
else
return 0;
}
//equal函数:判断两个数据元素是否相等的函数
//为LocateElem_Sq函数准备第三个实参
Status equal(ElemType x, ElemType y)
{
if(x==y)
return OK;
else
return ERROR;
}