1、线性表的定义和基本操作
1、1 线性表的定义
线性表示一种线性结构,它是具有相同数据类型的n个数据元素的有限序列。(其中n为表长,当n = 0 时线性表是一个空表)。若用L命名线性表,则其一般表示为:
L = (a1,a2,a3,......ai,a(i+1),......an)
在上述表达式中,a1是唯一的第一个数据元素,又称为表头元素;an是唯一的最后一个数据元素,又称为表尾元素。除表头元素外,每个元素有且仅有唯一的前驱。除表尾元素外,每个元素有且仅有唯一的后继。这就是线性表的逻辑特性,也是其名称的由来。
线性表的特点:
1、序列性。线性表中的元素是有序的,表中元素具有逻辑上的顺序性,表中元素有其先后次序。
2、有限性。线性表中的元素个数是有限的,即线性表不是一个无限序列。
3、同一性。线性表中的元素具有相同的数据类型,这意味着每个元素占有相同大小的存储空间。
4、此外,线性表中的元素都是数据元素,每个元素都是单个元素;表中的元素也具有抽象性,即仅讨论元素间的逻辑关系,而不考虑元素究竟代表什么内容。
1、2 线性表的基本操作
一个数据结构的基本操作是指其最核心、最基本的操作。其他较复杂的操作可以通过调用其基本操作来实现。线性表的主要操作如下:
1、InitList(&L) 初始化表。 构造一个空的线性表L并为其分配必要的内存空间。
2、Length(L) 求表长。返回线性表L的长度,即L中数据元素的个数。
3、LocateElem(L,e) 按值查找操作。在表L中查找具有给定关键字值e的元素,并返回该元素在表中的位置(如果存在)。若表中不存在该元素,则返回某个特定的值(如 0 或 -1)表示查找失败。
4、GetElem(L,i) 按位查找操作。获取表L中第i个位置的元素的值。
5、ListInsert(&L,i,e) 插入操作。在表L中的第i个位置插入指定元素e。
6、ListDelete(&L,i,&e) 删除操作。删除表L中的第i个位置的元素,并用e返回删除元素的值。
7、PrintList(L) 输出操作。按前后顺序输出线性表L的所有元素值。
8、Empty(L) 判空操作。检查线性表L是否为空表,若L为空表,则返回true,否则返回false。
9、DestroyList(&L) 销毁操作。销毁线性表,并释放线性表L所占用的内存空间。
2、线性表的顺序表示
2、1 顺序表的定义
线性表的顺序存储又称顺序表。顺序表是将线性表中的所有表项按照其逻辑顺序依次存储到计算机内存中一块连续的存储空间中。这样,线性表中的第一个表项的存储位置就是被指定的存储位置,第i个表项(2=<i<=n)的存储位置紧接在第i-1个表项的存储位置的后面。顺序表中的各个表项的逻辑顺序与其存放的物理顺序一致,即第i个表项存储与第i个物理位置(1=<i<=n)。
又因为顺序表中的每个数据元素的存储位置都和顺序表的起始位置相差一个和该数据元素的位次成正比的常数,因此,顺序表中的任意一个数据元素都可以随机存取,所以线性表的顺序存储结构是一种随机存取的存储结构。(通常用数组来描述线性表的顺序存储结构,但要注意线性表中的元素的位序是从1开始的,而数组中的元素的下标是从0开始)
假设线性表的元素类型为ElemType,则静态分配的顺序表存储结构描述为
#define MaxSize 50 //表长度的初始定义
typedef struct
{
ElemType date[ MaxSize]; //顺序表的元素
int length; //顺序表的当前长度
}SqList; //顺序表的类型定义
动态分配的顺序表存储结构描述为
#define InitSize 100 //表长度的初始定义
typedef struct
{
ElemType* date; //指示动态分配数组的指针
int MaxSize,length; //数组的最大容量和当前个数
}SeqList; //动态分配数组顺序表的类型定义
C的初始动态分配语句为
L.date = (ElemType*)malloc(sizeof(ElemType)*InitSize);
C++的初始动态分配语句
L.date = new ElemType[InitSize];
2、2 顺序表的特点及优缺点
特点:
1、顺序存储。2、动态分配空间。3、支持随机访问和顺序访问。4、逻辑顺序与物理顺序一致。5、存储密度高。
优点:
1、访问元素速度快,特别是通过索引进行随机访问时。
2、存储密度高,空间利用率好。
缺点:
1、要求大片连续空间,在某些情况下难以满足。
2、改变容量不方便,尤其在元素数量频繁变化时,可能需要频繁地进行扩容或缩容操作。
注:顺序表上的基本操作以及线性表的链式表示会在下篇文章来进行说明