今天还真是无语,明明可以早点下班。哎!现在每天都不知道干什么了,看点CSDN的文章,打开电脑,不知道干什么,看了看163的新闻,对着电脑发呆!后来想到应该更新下博客,所以就坐下来,写写!
今天看看线性表,估计写不完,准备用两天来写。
线性表,顾名思义,线性,直线也,其实这里我们叫做线段最好,因为直线没有两端,没有长度,线段有两个端点,有长度。
先来看线性表的定义:N个数据元素的有限序列。
线性表的特点:存在一个起点,存在一个终点,除起点外,集合中的每个数据元素均只有一个前驱,除终点外,集合中的每个元素都只有一个后继。
线性表中的元素的个数定义为线性表的长度。
线性表的两种存储实现:
线性表的顺序存储:表示指的是用一组地址连续的存储 单元依次存储线性表的数据元素。换句话说,就是以元素在计算机内物理位置相邻来表示线性表中数据元素之间的逻辑关系。通常在高级语言中,用数组来描述数据结构中的顺序存储结构。
我们用如下的数据结构来表示线性表的动态分配的顺序存储结构:
#define LIST_INIT_SIZE 100
typedef struct {
ElemType *elem;
int length;
int listsize;
}SqList
比如,我们可以按照如下的方式来分配空间
SqList &L;
L. elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType));
由于线性表的顺序表示,物理位置相邻的两个元素在逻辑关系上也相邻,当在顺序存储结构的线性表中某个位置插入或者删除一个数据元素时,其时间主要耗费在移动元素上(换句话说:移动元素的操作为预估算法时间复杂度的基本操作),而移动元素的个数取决于插入和删除元素的位置。
我们再介绍另一种线性表的存储结构,线性表的链式存储结构。
线性表的链式存储结构的特点,是用一组任意的存储单元存储线性表的数据元素(这组存储单元的可以是连续的,也可以是不连续的)我们称这个存储单元为一个结点,它包括两个域,其中存储数据元素信息的域称为数据域,存储直接后继存储位置的域称为指针域。指针域中存储的信息称做指针或链。又由于此链表的每个结点只含有一个指针域,固有称为线性链表,或者单链表。
整个链表的存储必须从头指针开始,头指针指示链表中的第一个元素,线性表中的最后一个结点的指针域为空,NULL.
用线性链表来表示线性表时,数据元素之间的逻辑关系是由指针指示的。换句话说,指针为数据元素之间的逻辑关系的映像。
//--------------线性表的单链表存储结构------------------//
typedef struct LNode{
ElemType data;
struct LNode *next;
} LNode, *LinkList;
有时,我们在单链表的第一个结点之前附设一个结点,称为头结点。头结点的数据域可以不存储任何信息,也可存储如线性表的长度等类的附加信息。关于线性表的具体的实现,我们后面会讲到。这里我们只是阐述线性表的实现和本质。
静态链表:用数组描述的链表。
循环链表: 是另一种形式的链式存储结构。它的特点是表中最后一个结点的指针域指向头结点,整个链表形成一个环。由此,从表中任一结点出发均可找到表中其他结点。循环链表的操作和线性链表的操作一致,差别仅在于算法中的循环条件不是p或者p->next是否为空,而是他们是否等于头结点。
双向链表: 由于单链表中只有一个指示直接后继的指针域,由此,从某个结点出发只能顺指针往后查询其他结点。为克服单链表中的这种缺点,我们可以使用双向链表。
//----------------------线性表的双向链表存储结构-------------------------------------//
typedef struct DuLNode{
ElemType data;
struct DuLNode *prior;
struct DuLNode *next;
} DuLNode, *DuLNode;