第三章 线性表:零个或多个数据元素的有限序列。
线性表特点:(1)序列:元素之间有顺序;(2)第一个无前驱;(3)最后一个无后继;(4)其余每个都有且只有一个前驱和后继。(5)有限。
线性表的操作:(1)置空操作(2)查找操作(3)获得线性表长度(4)插入和删除操作
ADT List
Data
Operation
InitList (* L); //初始化操作,建立一个空的线性表
ListEmpty( L ); //判空操作,若线性表为空,返回true,否则,返回false。
ClearList (*L); //将线性表清空
GetElem(L,i,*e); //将线性表L中的第i个位置元素值返回给e
LocateElem(L,e); //在线性表L中查找与给定值e相等的元素,如果查找成功,返回该元素在表中的序号;否则,返回0表示失败。
ListInsert(*L,i,e); //在线性表L中的第i个位置插入新元素e
ListDelete(*L,i,*e); //删除线性表L中第i个位置元素,并用e返回其值
ListLength(L); //返回线性表L的元素个数
集合A和集合B的并集运算:
void union(List *La,List Lb)
{
int La_len,Lb_len,i;
La_len=ListLength(La);
Lb_len=ListLength(Lb);
ElemType e;
for( i=1; i<=Lb_len;i++ )
{
GetElem(Lb,i,e);
if(!LocateElem(La,e,equal) )
ListInsert(La,++La_len,e);
}
}
线性表的顺序存储结构:指的是一段地址连续的存储单元依次存储线性表的数据元素。
#define MAXSIZE 20
typedef int ElemType;
typedef struct
{
ElemType data[MAXSIZE];
int length;
} SqList;在任意时刻,线性表的长度应小于等于数组的长度。注意区分线性表的长度和数组的长度。
GetElem,ListInsert,ListDelete函数的实现
线性表顺序存储的优缺点:
优点:
1)无需为表示表中元素之间的逻辑关系而增加额外的存储空间;
2)可以快速存取表中任一位置的元素。
缺点:
1)插入和删除操作需要移动大量元素
2)当线性表长度变化较大时,难以确定存储空间的容量;
3)造成存储空间的“碎片”
线性表的链式存储结构:
数据域和指针域
头指针和头结点的异同:
(1)头指针:是指链表指向第一个结点的指针,若链表有头结点,则是指向头结点的指针。头指针具有标识作用,所以常用头指针冠以链表的名字。无论链表是否为空,头指针均不为空,头指针是链表的必要元素。
(2)头结点:是为了操作的统一和方便而设立的,放在第一元素的结点之前,其数据域一般无意义(也可存放链表的长度)。有了头结点,对在第一元素结点前插入结点和删除第一结点,其操作与其他结点的操作就统一了。头结点不一定是链表的必须元素。
typedef struct Node
{
ElemType data;
struct Node *next;
} Node;
typedef struct Node *LinkList;
GetElem,ListInsert,ListDelete函数的实现
void CreateListTail(LinkList *L,int n) :尾插法
void CreateListHead(LinkList *L,int n) :头插法
单链表结构与顺序存储结构优缺点:
(一)存储分配方式:
顺序存储结构用一段连续的存储单元依次存储线性表的数据元素;单链表采用链式存储结构,用一组任意的存储单元存放线性表的元素
(二)时间性能:
查找:
顺序结构O(1)
单链表O(n)
插入和删除:
顺序存储结构需要平均移动表长一半的元素,时间为O(n)
单链表在给出某位置的指针之后,插入和删除的时间仅为O(1)
(三)空间性能:
顺序存储结构需要预先分配存储空间,分大了浪费;分小了容易上溢。
单链表不需要分配存储空间,只要有就可以分配,元素个数也不受限制。
经验性的结论:(1)若需频繁查找,且很少插入和删除,则宜使用顺序存储结构。(2)若需频繁插入和删除,宜使用单链表结构。(3)当线性表中的元素个数变化较大或者根本不知道有多大时,最好用单链表结构。(4)若事先知道线性表的大小,则考虑使用顺序存储结构。
静态链表,也叫游标实现法,它使用数组来描述单链表,其中,数组的元素由两个数据域组成:数据(data)+游标(cur)
通常会将数组建的大一些,以便有一些空闲空间可以便于插入时不至于溢出。
#define MAXSIZE
typedef struct{
ElemType data;
int cur;
} Component,StaticLinkList[MAXSIZE];
另外,对数组的第一个元素和最后一个元素作为特殊元素处理,不存数据。将为被使用的数组元素成为备用链表。其中,数组的第一个元素,即下标为0的元素的cur就存放备用链表的第一个结点的下标;而数组的最后一个元素的cur则存放备用链表的第一个结点的下标,相当于单链表中头结点的作用。
静态链表的插入、删除操作
静态链表的优点:在插入和删除操作时,只需要修改游标,不需要移动元素,从而改进了在顺序存储结构中的插入和删除操作需要移动大量元素的缺点。
静态链表的缺点:没有解决连续存储分配带来的表长难以确定的问题;失去了顺序存储结构随机存取的特性。
循环链表
双向链表