线性表是最简单也是最常用的一种数据结构。
线性表定义:线性表是具有相同特性的数据元素的一个有限序列。该序列中所含元素的个数叫做线性表的长度,用n表示,n≥0。当n=0时,表示线性表是一个空表,表中不包含任何元素。设序列中第i(i表示逻辑序号)个元素为ai(1≤i≤n),则线性表的一般表示为:
(a1,a2,…,ai,ai+1,…,an)
其中a1为第一个元素,又称表头元素,an为最后一个元素,又称表尾元素。
一个线性表可以用一个标识符来命名,如用L来命名上面的线性表,则L=(a1,a2,…,an)
线性表中元素是与位置有关的,即第i个元素ai处在第i-1个元素ai-1的后面和元素ai+1的前面。这种位置上的有序性就是一种线性关系,所以线性表是一种线性结构,
用二元组表示:L=(D,R),
其中: D={ai|1≤i≤n,n≥0,ai 为ElemType类型}//ElemType是自定义的类型标识符
R={r}
r={< ai,ai+1>|1≤i≤n -1}
ADT List
{
数据对象:D={ai|1≤i≤n,n≥0,ai 为ElemType类型}//ElemType是自定义的类型标识符
数据关系:R={< ai,ai+1>|ai,ai+1∈D,i=1,…,n-1}
基本运算:初始化构造,销毁,判断是否为空,求长度,输出,第i个,查找,插入,删除
}
线性表的顺序存储是最常用的存储方式,它直接将线性表的逻辑结构映射到存储结构上,所以既便于理解,又容易实现。
线性表顺序存储结构,把线性表中的所有元素按照其逻辑顺序依次存储到从计算机存储器中指定中指定位置开始的一块连续存储空间中。由于逻辑与其存储位置皆相邻,所以这种映射称为直接映射。
假定线性表的元素类型为ElemType,则每个元素所占字节数为sizeof(ElemType),整个线性表所占用存储空间的大小为n×sizeof(ElemType),其中n为线性表长度。
线性表的顺序存储结构是利用数组实现的,数组基本类型为线性表元素的类型,数组大小(数组元素个数)大于等于线性表的长度。
在定义一个线性表的顺序存储类型时,除了定义一个数组来存储线性表中的所有元素外,还需要定义一个整型变量来存储线性表的实际长度。
Typedef struct
{ ElemType data[MaxSize]; //存放顺序表中元素
int length; //存放顺序表的长度
}SqList; //顺序表的类型定义
顺序表必须占用一整块事先分配大小的固定的存储空间,不便于存储空间的管理。为此提出了可以实现存储空间动态管理的链式存储方式——链表
链表是一种常见的重要的数据结构。它是动态地进行存储分配的一种结构。根据需要开辟内存单元。
链表有一个“头指针”变量,存放一个地址,该地址指向一个元素。
链表中每一个元素称为“结点”,每个结点都应包括两个部分:
(1)用户需要用的实际数据;
(2)下一个结点的地址。
最后一个元素不指向其他元素,称为“表尾”,它的地址部分放一个“NULL”(空地址),链表到此结束。
链表中各元素在内存中的地址可以是不连续的。要访问链表,必须要有“头指针”。
在链式存储中,每个存储节点不仅包含有元素本身的信息(称为数据域),而且包含有元素之间逻辑关系的信息,即一个节点中包含有后继节点的地址信息(称为指针域),这样可以通过一个节点的指针域方便地找到后继节点的位置。一般每个节点有一个或多个指针域。若一个节点中的指针域不需要指向任何节点,则将它的值置为空,用NULL表示。
由于线性表中元素之间是一对一的逻辑关系,因此采用链式存储时,最简单常用的方法是:在每个节点中除数据域外,只设置一个指向后继节点的指针域,此链表称为线性单向链接表(简称单链表);另一种可以采用的方法是设置两个指针域,指向其前驱节点和后继节点,构成的链接表称为线性双向链接表(简称双链表)。
为了便于插入和删除算法的实现,每个链表带有一个头节点,并通过头节点的指针唯一标识该链表。
typedef struct LNode //定义单链表节点类型
{ ElemType data; //存放元素值
struct LNode *next; //指向后继节点
}LinkList;
typedef struct DNode //定义双链表节点类型
{ ElemType data; //存放元素值
struct DNode *prior; //指向前驱节点
struct DNode *next; //指向后继节点
}DLinkList;
由于链表的每个节点都带有指针域,从存储密度来讲,这是不经济的。
存储密度:指节点数据本身所占的存储量和整个节点结构中所占的存储量之比,
即:存储密度=节点数据本身所占的存储量/节点结构所占的存储总量
存储密度越大,存储空间地利用率越高。顺序表存储密度=1,链表存储密度<1。
循环链表是另一种形式的链式存储结构。特点:表中尾节点的指针域指向头节点,整个链表形成一个环。因此,从表中任一节点出发均可找到链表中其他节点。
循环链表基本运算实现算法与非循环链表的算法基本相同,只是对表尾的判断作了改变。判断表尾节点的条件是p->next==L。L是头节点。
静态链表:所有结点都是在程序中定义,不是临时开辟,也不能用完后释放的链表。
动态链表:指在程序执行过程中从无到有地建立起一个链表,即一个一个地开辟结点和输入各结点数据,并建立起前后相链的关系。
有序表:指其中所有元素以递增或递减方式有序排列的线性表。
ADT OrderList
{
数据对象:D={ai|1≤i≤n,n≥0,ai 为ElemType类型}//ElemType是自定义的类型标识符
数据关系:R={< ai,ai+1>|ai,ai+1∈D,i=1,…,n-1}
基本运算:初始化,销毁,判断空表,求长度,输出,第i个,查找,插入,删除
}