线性表(上)之顺序存储

线性表
一、线性表定义:
1、线性表的定义
定义:线性表(List):零个或多个数据元素的有限序列。
注意:
1)线性表是一个序列。也就是说,线性表的元素之间是有序的。若元素存在多个,对于其中一个元素来说,它前面的元素叫前驱,后面的元素叫后继。第一个元素无前驱,最后一个元素无后继,中间的元素只有一个前驱,一个后继。
2)线性表是有限的。事实上,在计算机科学领域,我们只研究有限的序列,因为计算机的处理对象都是有限的。而对于那些无限的序列,只在数学中讨论。
线性表的元素个数n(n>=0)定义为线性表的长度,当n=0时,称为空表。
练习:说明以下数据集是否是线性表
1、一年中的十二星座
2、一个公司的组织架构(非皮包公司)
3、一个班级间的同学关系
4、班级同学的点名册
5、播放器的播放列表
6、linux的文件系统
答案:
1、4、5是,2、3、6不是

2、线性表的操作:
设有线性表L,对线性表的操作有:
⒈建立一个空线性表
⒉清空一个线性表
⒊判断线性表是否为空
⒋求表长
⒌获得表中第i个位置的元素
⒍确定某元素在线性表中的位置
⒎插入一个新的元素
⒏删除第i个位置的元素
⒐遍历该线性表
二、线性表的顺序存储结构
1、定义存储结构
线性表的顺序存储结构,指的是用一段地址连续的存储单元依次存储线性表的数据元素。
在C语言中,我们可以使用一维数组来实现顺序表的存储结构。即把表的第一个元素数据存放到数组下标为0的位置中,接着把线性表相邻的元素存储到数组中的相邻位置。
线性表的顺序存储结构代码:
#define MAXSIZE 20
typedef int data_t;
typedef struct
{
data_t data[MAXSIZE];
int length;
}SqList;
这里要区分线性表长度与数组长度的区别。数组长度是存放线性表的存储空间长度,在编译后这个存储空间就不变了。而线性表长度指的是线性表中的数据元素个数,随着线性表的操作,这个数据是变化的。在任意时刻,线性表长度应该小于等于数组长度。
对于顺序表来说,逻辑位置上相邻的两个元素,其在存储位置上也是相邻的。例如a[i]和a[i+1],二者在逻辑结构上是前后关系,在存储结构上也是前后关系。
2、插入与删除
有关于顺序表的相关操作,一些操作是十分简单的。例如:求表长,查询第i个位置元素,置空,遍历等。这里不详细讲解。对于顺序表来说,重点要掌握它的插入与删除操作。
1)获得元素
对于线性表的顺序存储结构来说,获取第i个位置的元素是非常简单的。
//代码见附录
2)插入操作
举个例子:一队人在排队买票,这时来了一个插队的,他插入到的队伍的第i个位置,那么在他之后的人都要向后挪一步。
在这个例子中我们已经说明了线性表的顺序存储结构在插入数据时的实现过程。
插入算法思路:
⒈如果插入位置不合理,返回异常
⒉如果线性表长度大于等于数组长度,则返回异常或增加容量
⒊从最后一个位置开始向前遍历到第i个位置,分别将它们都向后移动一个位置
⒋将要插入元素填入位置i处
⒌表长加1
//代码见附录
3)删除操作
接着刚才的例子:此时后边排队的人意见很大,这时他冲出了队伍,消失在人群中。于是排队的人群又想蠕虫一样向前移动了一步,队伍又恢复了平静。
这就是线性表的顺序存储结构删除元素的过程。
删除算法思路:
⒈如果删除位置不合理,返回异常
⒉取出删除元素
⒊从删除元素位置开始遍历到最后一个元素位置,分别将它们都向前移动一个位置
⒋表长减1
//代码见附录
3、线性表顺序存储结构的优缺点
优点:
⒈无需为表示表中元素之间的逻辑关系而额外增加额外的存储空间
⒉可以快速地存取表中任意位置的元素
缺点:
⒈插入和删除操作需要移动大量元素
⒉当线性表长度变化较大时,难以确定存储空间的容量
⒊可能造成存储空间“碎片”

线性表之顺序表代码
#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 20
#define OK 1
#define ERROR 0
typedef int data_t;
typedef struct
{
data_t data[MAXSIZE];//定长情况下
//data_t *data;//变长情况下
int length;//表长
}SqList;
SqList *CreateEmptySqList()//定长
{
SqList *sq;
if(NULL==(sq = (SqList*)malloc(sizeof(SqList))))
{
printf("CreateEmptySqList Error\n");
exit(0);
}
sq->length=0;
return sq;
}

int GetElem(SqList *L,int i,data_t *e)//获得顺序表第i个位置的元素
{
if(i>=L->length && i<0)
{
perror("No this Element");
return ERROR;
}
*e=L->data[i];
return OK;
}
int ListInsert(SqList *L,int i,data_t e)//在线性表的第i个位置插入元素e
{
int k;
if(L->length==MAXSIZE)//线性表已满
{
printf("SqList is Full\n");
return ERROR;
}
if(i<0 || i>L->length)//i不在线性表的范围内
{
printf("Position Error\n");
return ERROR;
}
if(i<L->length)//若插入位置不在表尾
{
for(k=L->length-1;k>=i;k--)//当前位置开始到表尾所有元素向后移动1格
L->data[k+1]=L->data[k];
}
L->data[i]=e;//插入新元素
L->length++;
return OK;
}
int ListDelete(SqList *L,int i,data_t *e)//删除线性表的第i个位置元素,并用e得到删除的值
{
int k;
if(L->length==0)//线性表为空
{
printf("SqList is Empty\n");
return ERROR;
}
if(i<0 || i>=L->length)//i不在线性表的范围内
{
printf("Position Error\n");
return ERROR;
}
*e=L->data[i];//取走元素
if(i<L->length-1)//若删除位置不在表尾
{
for(k=i;k<L->length-1;k++)
L->data[k]=L->data[k+1];
}
L->length--;
return OK;
}
int PrintList(SqList *L)//遍历打印整个顺序表
{
int k;
data_t temp=0;
if(L->length==0)
{
printf("线性表为空!\n");
return ERROR;
}
for(k=0;k<L->length;k++)
{
GetElem(L,k,&temp);
printf("%d\t",temp);
}
printf("\n");
return OK;
}
int main()
{
int i;
data_t data;
SqList *sq = CreateEmptySqList();
for(i=0;i<5;i++)
{
sq->data[sq->length]=i;
sq->length++;
}
if(GetElem(sq,3,&data)==OK)
{
printf("data is %d\n",data);
}
PrintList(sq);
ListInsert(sq,2,20);
PrintList(sq);
ListDelete(sq,2,&data);
PrintList(sq);
return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章