开始介绍线性表之前我们先讲个例子。一天,李豆豆的邻居有些事情,麻烦李豆豆同学去接一下自家的小孩,说自家的小孩排在第七个。李豆豆来到了校门口,发现邻居小孩果然在第七个,小朋友出校门的时候也是一个拉着另一个的手,很有次序的往外走。李豆豆同学很好奇,就问老师原因,老师说,为了保证小朋友的安全,就提前安排好了小朋友出校门的顺序,每一位小朋友的前后顺序都是固定的,这样就算有一位小朋友突然走失,他前后的小朋友也可以很快的报告老师有位小朋友不见啦。李豆豆一想,的确很有道理,遵守秩序要从娃娃抓起。这种排好队的组织方式就是下面要介绍的数据结构:线性表。
1.1线性表及其逻辑结构
1.1.1线性表的定义
零个或多个数据元素的有限序列。 说明,线性表强调的是有限的,李豆豆邻居家小朋友所在的班级人数就是固定的,所以元素个数也是有限的。除过第一个和最后一个小朋友,每一个小朋友前面都有一个直接前驱小朋友(元素),后面有一个直接后继小朋友(元素)。
1.1.2线性表的基本操作
操作 | 函数名 | 说明 |
---|---|---|
线性表初始化 | Init_List(L) | 构造一个空的线性表 |
求线性表长度 | Length_List(L) | 返回线性表中所含元素个数 |
取表元 | Get_List(L,i) | 返回线性表L中第i个元素的值或地址 |
按值查找 | Locate_List(L,x) | 在线性表L中查找值为x的数据元素,其结果返回在L中首次出现的,值为x的元素的地址;若未找到,返回一个特殊值表示查找失败 |
插入操作 | Insert_List(L,i,x) | 在线性表L的第i个位置插入一个值为x的新元素 |
删除操作 | Delet_List(L,i) | 删除线性表L中序号为i的数据元素 |
1.2线性表的顺序存储结构及运算实现
1.2.1顺序表的顺序存储——顺序表
顺序存储是指在内存中用一片连续的地址空间将数据元素按其逻辑关系依次存放起来。 顺序存储结构的线性表简称“顺序表”。
设a1的存储地址为Loc(a1),每个数据元素占d个存储位置,则第i个元素的地址为:Loc(ai)=Loc(a1)+(i-1)*d
顺序表的类型定义:
typedef struct
{
datatype data[MAXSIZE];
int len;
}SeqList;
说明
- datatype为抽象出的数据类型。
- MAXSIZE为线性表中最多可以存放的元素个数。
- len为表长。
- 为方便操作,约定元素从1位置开始存放。
定义一个顺序表L1的方法一:
SeqList L1;
!
定义一个顺序表L2的方法二:
SeqList *L2;
1.2.2顺序表上基本运算的实现
- 顺序表的初始化(构造一个空表)
SeqList *Init_SeqList()
{
SeqList *L;
L=(SeqList*)malloc(sizeof(SeqList)); //申请空间
L->len=0; //空表,表长为0
return 0;
}
初始化函数的调用:
main()
{
SeqList *q;
q=Init_SeqList();
…
}
- 建立顺序表
void CreatList(SeqList *L)
{
int i,n;
printf("Input the length of list : ");
scanf("%d",&n); //输入表长
printf("Input elements of list :\n ");
for(i=1;i<n;i++)
scanf("%d",&L->data[i]); //输入元素
L->len=n; //表长重置
}
- 插入运算
插入过程:
第一步:元素后移
第二步:插入元素
第三步:表长加1
不能插入的情况:表满、位置不对
void Insert_SeqList(SeqList *L,int i,datatype x)
{
int j;
if(L->len==MAXSIZE-1) //表中元素等于表长
printf(“list is full!");
else if(i<1||i>L->len+1) //插入位置超前或超出表长
printf("position is wrong!");
else
{
for(j=L->len;j>=i;j--)
L->data[j+1]=L->data[j]; //元素后移
L->data[i]=x; //x赋给当前位置
L->len++; //表长加一
}
}
说明:
(1)大于MAXSIZE—1溢出。
(2)1<=i<=n+1位置有效。
(3)数据移动的方向。
- 删除运算
删除过程:
第一步:元素前移
第二步:表长减1
不能删除的情况:表空、位置不对
void Delete_SeqList(SeqList *L,int i)
{
int j;
if (L->len==0) //表为空
printf("the list is empty!");
else if(i<1||i>L->len)
printf("this element don't exist!");
else
{
for(j=i+1;j<=L->len;j++)
L->data[j-1]=L->data[j]; //元素前移
L->len--; //表长减一
}
}
说明:
(1)1<=i<=n删除位置有效。
(2)表空时不能删除。
- 查找运算
int Location_SeqList(SeqList *L,datatype x)
{
int i=1; //从第一个开始查找
while(i<=L->len&&L->data[i]!=x) //没找完且没找到
i++;
if(i>L->len)
return(0);
else return(i); //找到返回当前位置
}
上述算法还可改进:
int Location_SeqList(SeqList *L,datatype x)
{
i=L->len;
L->data[0]=x;
while(L->data[i]!=L->data[0])
i--;
return i;
}