线性表
:n个数据元素(A1,A2......An)的有限序列,大小为0的表为空表。


前驱:在非空表中我们称A(i+1)是Ai前驱。
后继:在非空表中我们称A(i--1)是Ai后继。
1.线性表的顺序表示
用一组地址连续的顺序存储单元一次存储线性表的数据元素。(通常使用数组来实现)
插入和删除最坏情况都需要O(N)。
2.线性表的链式表示
1链表
链表由一系列不必在内存中相连的结构组成,每一个结构均含有表元素和指向包含该元素后继元的结构指针。最后一个元素的后继指针指向NULL。
该结构(又称为结点)由两个域组成:数据域和指针域,数据域存储数据元素信息,指针域存储后继结点的地址。
typedef struct LNode
{
ElemType data;
struct LNode *next;
}LNode, *LinkList;
如果L为LinkList型的变量,则L为单链表的头指针,它指向表中第一个结点。如果L为空则表为空。
有时候我们附设一个头结点,数据域可以不存储数据,也可以存储如线性表长度等的附加信息,指针域存储第一个结点的指针,称之为
头结点。
1.1 单链表的创建
单链表的创建一般有两种方法:头插法和尾插法。
头插法
从一个空表开始,创建新结点,将输入的数据存放到新结点的数据域中,然后将新结点插入到当前链表的表头上,直到结束为止。简单来说,就是把新加进的元素放在表头后的第一个位置,如图所示
代码如下:
LinkList creatListHead(int n)
{
int i;
int e;
LinkList L,p;
//创建头结点
L = (LinkList)malloc(sizeof(LNode));
L->next =NULL;
for(i=1;i<=n;i++)
{
p = (LinkList)malloc(sizeof(LNode));
scanf("%d",&e);
p->data = e;
p->next = L->next;
L->next = p;
}
return L;
}
尾插法
从字面意思可以理解为在表的最后插入结点。从一个空表开始,创建新结点,将输入的数据存放到新结点的数据域中,然后将新结点插入到当前链表的表尾上,直到读入结束标志为止。如图所示
代码如下
LinkList creatListTail(int n)
{
int i;
int e;
LinkList L,r,p;
//创建头结点
L = (LinkList)malloc(sizeof(LNode));
r = L;
for(i=1;i<=n;i++)
{
p = (LinkList)malloc(sizeof(LNode));
scanf("%d",&e);
p->data = e;
r->next = p;
r = p;
}
r->next=NULL;
return L;
}
1.2单链表的删除
单链表的删除命令可以通过修改一个指针来实现,如图所示:
代码如下:
//删除链表第n个元素。
int deleteList(LinkList L,int n)
{
if(L->next==NULL)
return 0;
LinkList p,q;
p = L;
for(int i=1;i<n;i++)
{
L = L->next;
p = L;
}
if(!(p->next))
return 0;
q = p->next;
p->next = q->next;
free(q);
return 0;
}
1.3单链表的插入
单链表的插入需要使用malloc调用从系统得到一个新单元并在之后执行两次指针调整,如图所示:
代码如下
//假设插入到第n个结点的前面,插入的元素为e
void insertList(LinkList L,int n,int e)
{
if(n<=0)
return ;
LinkList p,s;
s = (LinkList)malloc(sizeof(LNode));
s->data = e;
p = L;
for(int i=1;i<n;i++)
{
L = L->next;
p = L;
}
if(!(p->next))
return;
s->next = p->next;
p->next = s;
return ;
}
2循环链表
表中最后一个结点的指针指向头结点,整个链表形成一个环。
循环链表的操作和线性链表基本一致,差别仅在于算法中的循环条件。(不是P为空或者p->next为空,而是他们是否等于头指针)
2双向链表
在双向链表中结点有两个指针域,一个指向直接后继,另一个指向直接前驱
双向链表的描述可以如下:
typedef struct DuLNode
{
ElemType data;
struct DuLnode *prior;
struct DuLnode *next;
}DuLnode,*DuLinkList;
和单链表类似,双向链表也有
循环表,如图所示: