线性表的链式存储结构:
指用一组任意的存储单元存储线性表的数据元素,这组存储单元可以是连续的,也可以是不连续的(意味着地址可以不连续)。它不仅要存储数据,还要存储一个指向它的后继元素的地址(有且只有一个后继元素)。
储存数据的叫数据域,储存指针的叫指针域,这两个组成的数据元素的存储映像叫结点。(知道结点是什么就行了,就是数据域+指针域)
单链表:链表的每个结点只含一个指针域
头指针(必要元素):链表中第一个结点的存储位置(是指向第一个结点的地址的指针)
头结点(可有可无,方便操作):其数据域一般存储线性表的长度,指针域指向第一个结点。(注意:若引入头结点,则头指针指向头结点)
链表的最后一个结点指向空(也就是指向NULL)。
typedef struct Node
{
type data; //数据域
struct Node *next; //指针域
}Node;
假设 p 是指向结点 ai 的指针,则用p —> data访问 ai的数据域,用p—> next 访问ai的指针域,则p—> next 就指向结点ai+1。
由于只知道链表的第一个结点的位置,所以想要访问第 i 个结点需要从第一个结点开始遍历链表直到第i个。 O(n)
单链表的插入和删除:
假设指针 p 指向结点ai,ai的下一结点为ai+1,想把结点 s 插入 ai 和 ai+1之间。只需先让 s 的指针域指向ai+1,再让 ai 的指针域指向 s 就行了,顺序不能调换,否则ai+1的地址会丢失掉。 O(1)
假设 p 指向结点ai-1,ai-1的下一个结点是ai,ai的下一个结点是ai+1,想要删除ai,只需让ai-1直接指向ai+1就行了。 O(1)
由上面可知,单链表在存入和读取数据的时间复杂度为O(n),在插入和删除的时间复杂度为O(1)。比较适合用于频繁进行插入和删除操作。