(本文是根据b站小甲鱼的数据结构与算法的视频进行的笔记,致力于加强记忆和便于复习)
线性表的链式存储结构
顺序存储结构在插入和删除时需要移动大量元素耗费时间,这是由于相邻元素存储位置具有邻居关系,内存中位置是紧挨着的,中间没有空隙就无法快速插入和删除。
链式存储结构定义:
用一组任意的存储单元存储线性表的数据元素,这组存储单元可以存在内存中未被占用的任意位置。
相比于顺序存储结构链式存储结构中除了要存储数据元素信息外,还要存储它的后继元素的存储地址(指针)。
我们把存储数据元素信息的域称为数据域,把存储直接后继位置的域称为指针域。指针域中存储的信息称为指针或链。这两部分信息组成数据元素称为存储映像,即结点(Node)。
n个结点链接成一个链表,即为线性表(a1,a2,a3…,an)的链式存储结构。
因为此链表每个结点中只包含一个指针域,所以叫做单链表。
我们把链表的第一个结点的存储位置叫做头指针,最后一个结点指针为NULL,头结点的数据域一般不存储任何信息。
头指针和头结点的区别:
头指针:
头指针是指链表指向第一个结点的指针,若链表有头结点,则是指向头结点的指针。
头指针具有标识作用,常用头指针冠以链表的名字
无论链表是否为控,头指针均不为空。
头指针是链表的必要元素。
头结点
头结点是为了操作的统一和方便而设定的,放在第一个元素的结点之前,其数据域一般无意义。
有了头结点,对在第一元素结点前插入结点和删除第一结点起操作与其它结点的操作就统一了。
头结点不一定是链表的必须要素。
单链表存储结构(C语言)
typedef struct Node
{
ElemType data; //数据域
struct Node* Next; //指针域
}Node;
typedef struct Node* LinkList;
假如p是指向线性表第i个元素的指针,则该结点ai的数据域我们可以用p->data的值是一个数据元素,结点ai的指针域可以用p->next来表示,p->next的值是一个指向第i+1个元素的指针。
单链表的读取
在线性表的顺序存储结构中,我们要计算任意一个元素的存储位置是很容易的。但在单链表中,由于第i个元素到底在哪无法在一开始就知道,所以要从第一个结点开始挨个找。
思路:
声明一个结点p指向第一个结点,初始化j从1开始;
当j<i时,遍历链表,让p的指针向后移动,不断指向下一个结点;
若到链表末尾p为空,则说明第i个元素不存在;
查找成功则返回结点p的数据。
代码
Status GetElem(LinkList L, int i ,ElemType *e)
{
int j;
LinkList p;
p = L->next;
j = 1;
while(p && j<i)
{
p = p->next;
++j;
}
if(!p || j>i)
{