——如果代码存在问题,请务必评论告诉我,感激不尽
1.数据类型定义 struct ElemType
想要建立顺序表,必须先确定顺序表中数据的类型,我这里用的是struct结构体类型,一般的类型(int,char,float)比较简单,所以我就没用(#^.^#),大家可以根据自己的需要进行修改。
typedef struct ElemType
{//元素类型
char name[20];
int age;
char sex[10];
}ElemType;
2.顺序表类型定义 struct SqeList
数据类型建立好之后就可以建顺序表了,因为是静态顺序表,所以我们用数组来装数据;另外顺序表中还需要一个变量(length)来描述当前顺序表中的元素个数,这样可以方便我们操作;另外一点,数组元素个数MAXSIZE是宏定义的。
typedef struct SqeList
{//顺序表
ElemType data[MAXSIZE];
int length;
}SqeList;
3.顺序表初始化 InitList(&L)
这个比较简单,要说明的是结构体数组的初始化可以使用memset函数来实现(头文件是string.h)。
void InitList(SqeList* L)
{//初始化
//结构体数组初始化 memset(arr,0,sizeof(arr)),头文件<string.h>
memset(L->data,0,sizeof(L->data));
L->length =0;
}
4.在位序i上插入数据ListInsert(&L,i,e)
虽然这里的e不改变他的真实值,可以直接传数据,但由于结构体的空间占用比较大,传地址会更高效,所以只要涉及到结构体,我传的大多数是const型的结构体地址,直接传值也是可以的;值得注意的是,位序是从1开始的,而数组的下标是从0开始的,这一点让我挺头疼的o(╥﹏╥)o
bool ListInsert(SqeList* L,int i,const ElemType* e)
{//在位序i上插入数据
if(i>=1&&i<=(L->length+1)&&L->length<MAXSIZE)
{
int j=0;
for(j=L->length-1;j>=i-1;j--)
{
L->data[j+1]=L->data[j];
}
L->data[i-1]=*e;
L->length++;
return true;
}
printf("插入失败\n");
return false;
}
5.删除位序i上的数据 ListDelete(&L,i,e)
因为是顺序表,我们找到对应位序的数据地址是很容易的,所以一般都是按位删除,当然也可以按值删除,不过稍微麻烦一点(一个一个遍历比较,然后找到第一个相同的数据,然后进行删除)。
bool ListDelete(SqeList* L,int i,ElemType* e)
{//删除位序i上的数据
if(i<=0||i>L->length)
{
printf("删除失败\n");
return false;
}
*e=L->data[i-1];
int j=0;
for(j=i-1;j<L->length-1;j++)
{
L->data[j]=L->data[j+1];
}
L->length--;
return true;
}
6.比较数据是否相同 ElemCompare(e1,e2)
由于数据的比较是很常用的,所以我们把他封装出来,这样我们下次用的时候只需要调用就可以了。
int ElemCompare(const ElemType* e1,const ElemType* e2)
{//数据比较,相同返回1,不同返回0 ,不同数据类型的比较方式会不同
if(strcmp(e1->name,e2->name)==0&&strcmp(e1->sex,e2->sex)==0&&e1->age==e2->age)
{
return 1;
}
return 0;
}
7.查询数据所在的位序 LocateElem(L,e)
int LocateElem(const SqeList* L,const ElemType* e)
{//查找数据,返回位序
int i=0;
for(i=0;i<L->length;i++)
{
if(ElemCompare(L->data+i,e)==1)
{
return i+1;
}
}
return 0;//返回找到元素的位序,0表示不存在
}
8.单个数据的打印输出 ElemPrint(&L,i)
void ElemPrint(SqeList* L,int i)
{
printf("%s %d %s \n",L->data[i-1].name,L->data[i-1].age,L->data[i-1].sex);
}
9.顺序表的遍历及打印 ListTraverse(L)
如果你想要遍历做别的事情,可以根据需要修改循环里的内容。
void ListTraverse(SqeList* L)
{
int i=0;
for(i=1;i<=L->length;i++)
{
ElemPrint(L,i);
}
}
9.得到第i个位序上的数据 GetElem(L,int i,&e)
因为我们想要得到数据,所以函数的参数需要有一个ElemType* e 类型的,我们通过将主函数中变量的地址传入到函数中,(求出所需数据),解引用将数据传到主函数里。
bool GetElem(const SqeList* L,int i,ElemType* e)
{//取第i个位序上的数据
if(i<1||i>L->length)
{
return false;
}
else
{
*e=L->data[i-1];
return true;
}
}
10.判断是否为空表 ListEmpty(L)
bool ListEmpty(const SqeList* L)
{//判断是否为空表
if(L->length==0)
{
return true;
}
return false;
}
11.全部代码
#include<stdio.h>
#include<string.h>
#include<stdbool.h>
#define MAXSIZE 5
void menu()
{
printf("*************************************\n");
printf("***1.插入数据 2.删除数据*******\n");
printf("***3.打印数据表 4.查找数据位序***\n");
printf("***5.按位查找数据 6.初始化数据表***\n");
printf("***0.退出程序************************\n");
}
typedef struct ElemType
{//元素类型
char name[20];
int age;
char sex[10];
}ElemType;
typedef struct SqeList
{//顺序表
ElemType data[MAXSIZE];
int length;
}SqeList;
void InitList(SqeList* L)
{//初始化
//结构体数组初始化 memset(arr,0,sizeof(arr)),头文件<string.h>
memset(L->data,0,sizeof(L->data));
L->length =0;
}
bool ListEmpty(const SqeList* L)
{//判断是否为空表
if(L->length==0)
{
return true;
}
return false;
}
int ListLength(const SqeList* L)
{//返回顺序表元素个数
return L->length;
}
bool GetElem(const SqeList* L,int i,ElemType* e)
{//取第i个位序上的数据
if(i<1||i>L->length)
{
return false;
}
else
{
*e=L->data[i-1];
return true;
}
}
int ElemCompare(const ElemType* e1,const ElemType* e2)
{//数据比较,相同返回1,不同返回0 ,不同数据类型的比较方式会不同
if(strcmp(e1->name,e2->name)==0&&strcmp(e1->sex,e2->sex)==0&&e1->age==e2->age)
{
return 1;
}
return 0;
}
int LocateElem(const SqeList* L,const ElemType* e)
{//查找数据,返回位序
int i=0;
for(i=0;i<L->length;i++)
{
if(ElemCompare(L->data+i,e)==1)
{
return i+1;
}
}
return 0;//返回找到元素的位序,0表示不存在
}
bool ListInsert(SqeList* L,int i,const ElemType* e)
{//在位序i上插入数据
if(i>=1&&i<=(L->length+1)&&L->length<MAXSIZE)
{
int j=0;
for(j=L->length-1;j>=i;j--)
{
L->data[j+1]=L->data[j];
}
L->data[i-1]=*e;
L->length++;
return true;
}
printf("插入失败\n");
return false;
}
bool ListDelete(SqeList* L,int i,ElemType* e)
{//删除位序i上的数据
if(i<=0||i>L->length)
{
printf("删除失败\n");
return false;
}
*e=L->data[i-1];
int j=0;
for(j=i-1;j<L->length-1;j++)
{
L->data[j]=L->data[j+1];
}
L->length--;
return true;
}
void ElemPrint(SqeList* L,int i)
{
printf("%s %d %s \n",L->data[i-1].name,L->data[i-1].age,L->data[i-1].sex);
}
void ListTraverse(SqeList* L)
{
int i=0;
for(i=1;i<=L->length;i++)
{
ElemPrint(L,i);
}
}
int main()
{
int i=0;
int input=0;
SqeList L1;
ElemType e1;
InitList(&L1);
do
{
menu();
printf("选择操作:");
scanf("%d",&input);
switch(input)
{
case 1:
printf("分别输入插入数据的姓名年龄性别:\n");
scanf("%s%d%s",e1.name,&(e1.age),e1.sex);
ListInsert(&L1,L1.length+1,&e1);
break;
case 2:
printf("输入要删除的数据所在位序:\n");
scanf("%d",&i);
ListDelete(&L1,i,&e1);
printf("删除的数据是:\n");
printf("%s %d %s \n",e1.name,e1.age,e1.sex);
break;
case 3:
ListTraverse(&L1);
break;
case 4:
printf("输入要查找的数据:\n");
scanf("%s%d%s",e1.name,&(e1.age),e1.sex);
i=LocateElem(&L1,&e1);
if(i==0)
{
printf("没有此数据\n");
}
else
{
printf("该数据的位序为:%d\n",i);
}
break;
case 5:
printf("输入要查找的数据位序:\n");
scanf("%d",&i);
GetElem(&L1,i,&e1);
printf("%d位上的数据为:\n",i);
printf("%s %d %s\n",e1.name,e1.age,e1.sex);
break;
case 6:
InitList(&L1);
printf("初始化成功\n");
break;
default:
printf("选择错误,重新选择\n");
break;
}
}while(input);
return 0;
}