线性表及其链式表示
线性链表
线性表的链式存储结构的特点是用一组任意的存储单元存储线性表的数据元素(这组存储单元可以是连续的,也可以是不连续的)。因此,为了表示每个数据元素ai与其直接后继元素ai+1之间的逻辑关系,对数据元素ai来说,除了存储其本身的信息之外,还需存储一个指示其直接后继的信息(即直接后继的存储位置)。这两部分信息组成的数据元素ai的存储映像,称为 节点 (node)。它包括两个域:其中存储数据元素信息的域称为数据域;存储直接后继元素存储位置的域称为指针域。指针域中存储的信息乘坐指针或链。n个节点(ai(1 <= i <= n)的存储映像)链结成一个链表,即为线性表(a1,a2,…,an)的链式存储结构。又由于此链表的每个节点中只包含一个指针域,固又称线性链表或单链表
线性链表与线性表的顺序表比较
线性表的顺序存储结构的特点是逻辑关系上相邻的两个元素在物理位置上也相邻。因为线性表的顺序存储方式是使用数组来存放数据的,而数组是计算机内存上一段连续的存储空间。但是链表不要求逻辑上相邻的元素在物理位置上也相邻,因为链表的元素之间使用指针一一相连的,后一个节点的位置信息储存在前一个节点的指针域中,因此即使它们相隔十万八千里,也可以通过指针这条高速公路互相连接。
顺序存储结构的特点决定了它存在一系列弱点,例如在进行插入和删除操作时,必须移动大量元素。但是链表不存在这种缺点,但是也失去了顺序表可随机存储的优点。
线性表的链式存储的表示和实现
- 生成节点
typedef struct LNode
{
ElemType data;
struct LNode *next;
}L, *List;
- 求表长
int Length(List PtrL)
{
int i = 1;
while(PtrL -> next)
{
PtrL = PtrL -> next;
i ++;
}
return i;
}
- 查找链表中值为x的元素,返回其第一次出现位置
List Find(ElemType x, List PtrL)
{
List p = PtrL;
while(p -> data != x && p)
p = p -> next;
if(p -> data == x)
return p;
else
return NULL;
}
- 在第i-1(1 <= i <= n + 1)个节点后插入一个值为x的新节点
List Insert(List PtrL, ElemType x, int i)
{
int count = 1;
List PtrNew, p;
PtrNew = (List)malloc(sizeof(L));
PtrNew -> data = x;
PtrNew -> next = NULL;
p = PtrL;
while(count <= i - 1)
{
p = p -> next;
count ++;
}
if(i == 1)
{
PtrNew -> next = p;
return p;
}
else
{
PtrNew -> next = p -> next;
p -> next = PtrNew;
return p;
}
}
- 删除链表的第i(1 <= i <= n)个位置上的节点
List Delete(List PtrL, int i)
{
int count = 1;
List p, temp;
p = PtrL;
while(count < i)
{
p = p -> next;
count ++;
}
temp = p;
p = p -> next;
free(temp);
return p;
}