【数据结构与算法】 通俗易懂讲解 链表

链表(Linked list)是一种线性表,可是并不会在物理存储上按线性的顺序存储数据,而是在每个节点里存到下一个节点的指针(Pointer)。因为没必要须按顺序存储,链表的插入和删除操做能够达到O(1)的复杂度。本文将讲解单向链表和双向链表,其中双向链表会给出部分关键代码实现。node

单向链表

单向链表(单链表)是链表的一种,它由节点组成,每一个节点都包含下一个节点的指针,下图就是一个单链表,表头为空,表头的后继节点是"结点10"(数据为10的结点),"节点10"的后继结点是"节点20"(数据为10的结点),...
【数据结构与算法】 通俗易懂讲解 链表算法

单链表删除节点

咱们看看单链表删除节点的操做,好比说下面这个单链表中咱们要删除"节点30"。编程

删除以前:"节点20" 的后继节点为"节点30",而"节点30" 的后继节点为"节点40"。缓存

删除以后:"节点20" 的后继节点为"节点40"。服务器

【数据结构与算法】 通俗易懂讲解 链表

单链表添加节点

咱们再来看看单链表添加节点的操做,好比说下面这个单链表中咱们在"节点10"与"节点20"之间添加"节点15"数据结构

添加以前:"节点10" 的后继节点为"节点20"。并发

添加以后:"节点10" 的后继节点为"节点15",而"节点15" 的后继节点为"节点20"。ide

【数据结构与算法】 通俗易懂讲解 链表

双向链表

双向链表(双链表)是链表的一种。和单链表同样,双链表也是由节点组成,它的每一个数据结点中都有两个指针,分别指向直接后继和直接前驱。因此,从双向链表中的任意一个结点开始,均可以很方便地访问它的前驱结点和后继结点。通常咱们都构造双向循环链表。线程

双链表的示意图以下:
【数据结构与算法】 通俗易懂讲解 链表设计

表头为空,表头的后继节点为"节点10"(数据为10的节点);"节点10"的后继节点是"节点20"(数据为10的节点),"节点20"的前继节点是"节点10";"节点20"的后继节点是"节点30","节点30"的前继节点是"节点20";...;末尾节点的后继节点是表头。

不难看出,双向链表的节点定义能够用一个下面的结构体表示:

//双向链表节点结构
typedef struct dlink_node
{
    struct dlink_node *prev;
    struct dlink_node *next;
    void *val;  //能存储任意类型数据
}node;

双向链表删除节点

咱们看看双向链表删除节点的操做,好比说下面这个单链表中咱们要删除"节点30"。

删除以前:"节点20"的后继节点为"节点30","节点30" 的前继节点为"节点20"。"节点30"的后继节点为"节点40","节点40" 的前继节点为"节点30"。

删除以后:"节点20"的后继节点为"节点40","节点40" 的前继节点为"节点20"。
【数据结构与算法】 通俗易懂讲解 链表

双向链表删除节点的关键代码以下:

//删除节点pindex
pindex->next->prev = pindex->prev;
pindex->prev->next = pindex->next;
free(pindex); //注意释放节点

双向链表添加节点

咱们再来看看双向链表添加节点的操做,好比说下面这个双向链表在"节点10"与"节点20"之间添加"节点15"

添加以前:"节点10"的后继节点为"节点20","节点20" 的前继节点为"节点10"。

添加以后:"节点10"的后继节点为"节点15","节点15" 的前继节点为"节点10"。"节点15"的后继节点为"节点20","节点20" 的前继节点为"节点15"。
【数据结构与算法】 通俗易懂讲解 链表

双向链表添加节点的关键代码以下:

//将pnode节点插入到pindex以前
pnode->prev = pindex->prev;
pnode->next = pindex;
pindex->prev->next = pnode;
pindex->prev = pnode;

推荐阅读:

【福利】本身搜集的网上精品课程视频分享(上)
【系统设计】LRU缓存
【协议森林】05 我尽力 (IP协议详解)
【数据结构与算法】 通俗易懂讲解 位排序
【C++札记】C++11并发编程(一)开启线程之旅
【C++札记】C/C++指针使用常见的坑
【C++札记】静态库和动态库详解(上)

专一服务器后台技术栈知识总结分享

欢迎关注交流共同进步

【数据结构与算法】 通俗易懂讲解 链表

码农有道 coding

码农有道,为您提供通俗易懂的技术文章,让技术变的更简单!

相关文章
相关标签/搜索