摘要:讲解链表的理论基础,包括链表的定义、类型、存储方式以及基本操作。
目录
链表的定义
链表是一种通过指针串联在一起的线性结构,其每一个节点都由数据域(该节点存储的数据)和指针域(存放指向下一节点的指针)两部分组成。链表的入口节点即头节点定义为head。
链表的类型
单链表
最简单常见的一种链表就是单链表,其每一个节点由一个数据域和一个指向下一个节点的指针域组成,单向的,只能向前查询。
代码定义为:
struct ListNode
{
int value;//节点上存储的元素
ListNode* next;//指向下一节点的指针
};
双链表
每一个节点由一个数据域和两个指针域组成,一个指针指向下一个节点,一个指向上一个节点,因此支持双向查询。
代码定义为:
struct DoubleListNode
{
int value;//节点上存储的元素
ListNode* next;//指向下一节点的指针
ListNode* formar;//指向上一节点的指针
};
循环链表
将链表首尾相连,即构成循环链表。
链表的存储方式
与数组不同,数组在内存中是连续分布的,但链表在内存中是非连续分布的。因为链表是通过指针链接内存中的各个节点,各个节点在内存中是散乱分布的,取决于操作系统的内存管理。
链表的操作
删除节点
对于单链表,删除中间任一节点,只需要将前一节点的指针指向后一节点的后一节点即可,最好再手动释放掉删除的节点;删除头节点时,只需要将头节点指针向后移动一位即可。可以看出,链表删除的算法复杂度为O(1)。
在单链表中删除元素value,代码如下:
ListNode* RemoveValue(ListNode* head, int value)
{
/*删除头节点*/
while (head != NULL && head->value == value)
{
ListNode* temp = head;
head = head->next;
delete temp;
}
ListNode* cur = head;
/*删除其他节点*/
while (cur != NULL && cur->next != NULL)
{
if (cur->next->value = value)
{
ListNode* temp = cur->next;
cur->next = cur->next->next;
delete temp;
}
else
{
cur = cur->next;
}
}
return head;
}
添加节点
对于单链表,在中间添加任一节点,只需要将插入点前一节点的指针指向插入的节点,插入节点的指针指向插入点的后一节点;添加尾节点时,只需要将原尾节点的指针指向添加的节点,添加的节点指针置为null即可。可以看出,链表添加的算法复杂度依然为O(1)。
查找节点
链表不能像数组那样通过索引直接访问元素,访问元素必须经过遍历查找,链表查询的算法复杂度为O(n)。
小结
掌握链表的基本理论,从根本理解其与数组的不同,至关重要。
每日寄语
深窥自己的心,而后发觉一切的奇迹在你自己。 ——培根