线性表
线性表:零个或多个数据元素的有限序列。
线性表分为 顺序存储方式 和 链式存储方式。
这里我们主要实现顺序存储方式的线性表及其一些功能。
线性表的抽象数据结构类型
线性表属一种抽象数据类型,如int,float,double一样 只是结构更加复杂一些。
下面是线性表一些函数实现一些功能
InitList(Sqlist *L) 初始化操作,建立一个空的线性表
ListEmpty(Sqlist *L) 若线性表为空,返回ture,否则返回false
ClearList(Sqlist *L) 将线性表清空
GetElem(Sqlist L,int i,ElemType *e) 将线性表L中的第i个位置元素值返回给e
LocateElem(Sqlist L,ElemType e) 在线性表L中查找与给定值e相等的元素,如果查找成功,返回
该元素在表中序号表示成功;否则,返回0表示失败
ListInsert(Sqlist *L,int i,ElemType e) 在线性表L中的第i个位置插入新元素e
ListDelete(Sqlist *L,int i,ElemType *e) 删除线性表L中第i个位置元素,并用e返回其值
ListLength(Sqlist L) 返回线性表元素L的元素个数
线性表的顺序存储结构
顺序存储定义
线性表的顺序存储结构,指的是用一段地址连续的存储单元一次存储线性表的数据元素。
顺序存储方式
这里说明一下 “为什么会有很多的typedef 和define 这种很多的替换 直接写不应该会很方便吗?”
typedef的一些名字的变化是为了后面的代码 一些变量定义的解释 便于代码更好的理解
difine 控制一些常量 便于数据的整体改动 如果一些数据重复使用需要改动的话 再去细找会很容易出现错误
#define MAXSIZE 100
typedef int ElemType; 换一下名字更便于理解
typedef struct
{
ElemType data[MAXSIZE]; 存储数据的数组
int length; 数据长度
}Sqlist;
顺序存储插入与删除
代码实现
#define OK 1
#define ERROR 0
typedef int Status ;
Status GetElem(Sqlist L,int i,ElemType *e) 获取元素操作
{
if(ListEmpty(&L)) 判断是否为空
return ERROR;
if(i<1||i>L.length) 判断是否超出范围
return ERROR;
*e=L.data[i-1]; 该位置获取数据
return OK;
}
void ListInsert(Sqlist *L,int i,ElemType e) 插入操作
{
if(L->length==MAXSIZE) 判断是否超出范围
return ;
if(i<1||i>L->length+1) 判断是否为空
return ;
int j;
for(j=L->length-1;j>=i-1;j--) 插入后的元素整体后移
L->data[j]=L->data[j+1];
L->data[i-1]=e; 新元素插入
L->length++;
}
Status ListDelete(Sqlist *L,int i,ElemType *e) 删除操作
{
if(ListEmpty(L)) 判断是否为空
return ERROR;
if(i<1||i>L->length) 判断是否超出范围
return ERROR;
int j;
*e=L->data[i-1]; 该位置获取数据
for(j=i-1;j<L->length;j++)
L->data[j]=L->data[j+1]; 数据前移覆盖删除数据
L->length--;
return *e;
}
线性表顺序存储结构的优缺点
优点
- 无须为表示表中元素之间的逻辑关系而增加而外的存储空间
- 可以快速的存取表中任意位置的元素
缺点
- 插入和删除操作需要移动大量元素
- 当线性表长度变化较大时,难以确定存储空间的容量
- 造成存储空间的“空间”
完整代码
自己写的完整代码
一些功能的实现
#include <stdio.h>
#define MAXSIZE 100
#define OK 1
#define ERROR 0
typedef int ElemType;
typedef int Status ;
typedef struct
{
ElemType data[MAXSIZE];
int length;
}Sqlist;
void InitList(Sqlist *L)
{
L->length=0;
}
Status ListEmpty(Sqlist *L)
{
if(L->length==0)
return OK;
return ERROR;
}
void ClearList(Sqlist *L)
{
if(ListEmpty(L))
return;
int i;
for(i=0;i<L->length;i++)
L->data[i]=0;
L->length=0;
}
Status GetElem(Sqlist L,int i,ElemType *e)
{
if(ListEmpty(&L))
return ERROR;
if(i<1||i>L.length)
return ERROR;
*e=L.data[i-1];
return OK;
}
Status LocateElem(Sqlist L,ElemType e)
{
if(ListEmpty(&L))
return ERROR;
int i;
for(i=0;i<L.length;i++)
{
if(L.data[i]==e)
return i+1;
}
return ERROR;
}
void ListInsert(Sqlist *L,int i,ElemType e)
{
if(i<1||i>L->length+1)
return ;
int j;
for(j=L->length-1;j>=i-1;j--)
L->data[j]=L->data[j+1];
L->data[i-1]=e;
L->length++;
}
Status ListDelete(Sqlist *L,int i,ElemType *e)
{
if(ListEmpty(L))
return ERROR;
if(i<1||i>L->length)
return ERROR;
int j;
*e=L->data[i-1];
for(j=i-1;j<L->length;j++)
L->data[j]=L->data[j+1];
L->length--;
return *e;
}
int ListLength(Sqlist L)
{
return L.length;
}
int main()
{
Sqlist L;
InitList(&L);
printf("1.判断线性表为空表\n");
printf("2.清空线性表\n");
printf("3.查找线性表某位置的数据\n");
printf("4.查找某数据在线性表的位置\n");
printf("5.插入数据\n");
printf("6.删除数据\n");
printf("7.返回线性表的数据个数\n");
printf("8.打印所有数据\n");
printf("0.结束\n");
int a;
while(scanf("%d",&a),!(a==0))
{
switch(a)
{
int i,e,e1;
case 1:if(ListEmpty(&L))printf("Yes\n");else printf("No\n");break;
case 2:ClearList(&L);break;
case 3:
printf("请输入需要获取的位置:");scanf("%d",&i);
if(GetElem(L,i,&e1))
printf("%d\n",e1);
else
printf("输入错误\n");
break;
case 4:
printf("请输入需要获取数据:");scanf("%d",&e);
i=LocateElem(L,e);
if(i)
printf("位置为%d\n",i);
else
printf("没有该数据\n");
break;
case 5:
printf("请输入插入的位置:");scanf("%d",&i);
printf("请输入插入的数据:");scanf("%d",&e);
ListInsert(&L,i,e);break;
case 6:
printf("请输入删除的位置:");scanf("%d",&i);
printf("%d\n",ListDelete(&L,i,&e1));break;
case 7:printf("%d\n",ListLength(L));break;
case 8:
for(i=0;i<L.length;i++)
printf("%d\n",L.data[i]);
}
}
return 0;
}