标签:
线性结构的特点是:在非空的有限集合中,只有唯一的第一个元素和唯一的最后一个元素。第一个元素没有直接前驱元素,最后一个没有直接的后继元素。其它元素都有唯一的前驱元素和唯一的后继元素。
线性表是一种最简单的线性结构。线性表可以用顺序存储结构和链式存储结构存储,可以在线性表的任意位置进行插入和输出操作。
要想将线性表在计算机上实现,必须把其逻辑结构转化为计算机可识别的存储结构。线性表的存储结构主要有两种:顺序存储结构和链式存储结构。
线性表的顺序存储结构指的是将线性表中的元素存放在一组连续的存储单元中。这样的存储方式使得线性表逻辑上相邻的元素,其在物理存储单元中也是相邻的。采用顺序存储结构的线性表称为顺序表。
假设线性表有n个元素,每个元素占用m个存储单元,如果第一个元素的存储位置为LOC(a1),第i个元素的位置为LOC(an-1),由于顺序表中各元素之间是相邻的,因此,线性表的第i个元素的存储位置与第一个元素a1的存储位置满足一下关系:
LOC(an)=LOC(a1)+(i-1)*m
其中,第一个元素的位置LOC(a1)称为起始地址或基地址。
顺序表反映了线性表中元素的逻辑关系,只要知道第一个元素的存储地址,就可以得到线性表中任何元素的存储地址。同样,已知任何一个元素的存储地址都可以得到其他元素的存储地址。因此,线性表中的任何一个元素都可以随机存取,线性表的顺序存储结构是一种随机存取的存储结构。
由于在C语言中,数组可以随机存取且数组中的元素占用连续的存储空间,因此,我们采用数组描述线性表的顺序存储结构。线性表的顺序存储结构描述如下:
typedef int DataType;
typedef struct
{
DataType list[LISTSIZE];
int length; //当前存储的数据元素的个数。
}SeqList;
例如,如果要定义一个变量名为L的结构体,可以定义为SeqList L。如果要定义一个指向结构体指针的变量,可以定义为SeqList *L。
在顺序存储结构中,线性表的基本运算如下。该算法的实现保存在文件 SeqList.h
中
顺序表的初始化就是要把顺序表初始化为空的顺序表,只需要将顺序表的长度length置为0即可:
//顺序表的初始化操作
void InitList(SeqList *L) /*将顺序表初始化为空*/
{
L->length = 0; /*把顺序表的长度置为0*/
}
顺序表为空的标志就是顺序表的长度length为0.
//判断顺序表是否为空,为空返回1,否则返回0
int ListEmpty(SeqList L)
{
if (L.length==0)
{
return 1;
}
else
{
return 0;
}
}
查找分为两种:按序号查找和按内容查找。
按序号查找就是查找顺序表L中的第i个元素,如果找到,将该元素值赋值给e。查找第i个元素时,首先要判断要查找的序号是否合法,如果合法,获得对应位置的值,并返回1表示查找成功,否则,返回-1,表示错误。
//按序号查找操作,查找顺序表中的第i个元素
int GetElem(SeqList L, int i, DataType *e)
{
if (i<1 || i>L.length)
{
return -1;
}
*e = L.list[i - 1]; //将第i个元素赋值为e
return 1;
}
按内容查找就是查找顺序表L中与给定的元素e相等的元素。如果找到,返回该元素在顺序表中的序号;如果没有找到与e相等的元素,则返回-1,表示失败。
//按内容查找操作
int LocateElem(SeqList L, DataType e)
{
int i;
for ( i = 0; i < L.length; i++)
{
if (L.list[i] == e)
{
return i;
}
return -1;
}
}
插入操作就是在顺序表L中的第i个位置插入新元素e,使顺序表{a1,a2,…,an}变为{a1,a2,…,ai-1,e,ai,…,an},顺序表的长度也由n变成n-1.
在顺序表的第i个元素插入元素e,首先要将第i个位置以后的元素(包括第i个元素)依次向后移动一个位置,然后将元素e插入到第i个位置。移动元素时要从后往前移动元素,先移动最后一个元素,在移动倒数第二个元素,依次类推。
插入元素之前,要判断插入的位置是否合法,顺序表是否已满;在插入元素后,要将表长增加1。
//插入操作。
//在顺序表的第i个元素插入元素e,插入成功返回1,
//如果插入位置不合法,返回-1,顺序表满返回0.
int InsertList(SeqList *L, int i, DataType e)
{
int j;
if (i<1 || i>L->length + 1)
{
printf("插入位置i不合法!\n");
return -1;
}
else if (L->length >= LISTSIZE)
{
printf("顺序表已满,不能插入元素。\n");
return 0;
}
else
{
//将第i个位置以后的元素依次后移
for ( j = L->length; j >= i; j--)
{
L->list[j] = L->list[j - 1];
}
L->list[i - 1] = e; //插入元素到第i个位置
L->length++;
return 1;
}
}
删除操作就是将顺序表L中的第i个位置元素删除,使顺序表{a1,a2,…,ai-1,ai,ai+1,…,an}变为{a1,a2,…,ai-1,ai+1,…,an},顺序表的长度也又n变成n-1。
为了删除第i个元素,需要将第i+1及其后面的元素依次向前移动一位,将前面的元素覆盖掉。移动元素时要先将第i+1个元素移动到第i个位置,在将第i+2个元素移动到第i+1个位置,依次类推,直到最后一个元素移动到倒数第二个位置。最后将顺序表的长度减1.
在进行删除操作时,要首先判断顺序表中是否有元素,还要判断删除的序号是否合法,删除成功要将表长减1.
//删除操作
int DeleteList(SeqList *L, int i, DataType *e)
{
int j;
if (L->length <= 0)
{
printf("顺序表已空不能进行删除!\n");
return 0;
}
else if (i<1 || i>L->length)
{
printf("删除位置不合适\n");
return -1;
}
else
{
*e = L->list[i - 1];
for ( j = i; j < L->length-1; j++)
{
L->list[j - 1] = L->list[j];
}
L->length--;
return 1;
}
}
删除操作中函数形参i的合法范围是1<=i<=L-<length
,当i等于1时,表示要删除第一个元素,对应C语言数组中的第0个元素;当i=L->length
时,表示要删除的是最后一个元素,对应C语言数组中的最后一个元素。
线性表的长度就是顺序表中的元素个数,只需要返回顺序表L的length域值。
//返回顺序表的长度操作。
int ListLength(SeqList L)
{
return L.length;
}
顺序表的清空操作就是将顺序表中的元素删除。要删除顺序表中的所有元素,只需要将顺序表的长度置为0即可。
//清空操作
void ClearList(SeqList *L)
{
L->length = 0;
}
标签:
原文地址:http://blog.csdn.net/u011026329/article/details/51344476