C语言类的双向链表详解

C语言类的双向链表详解

基本概念

什么是双向链表?

双向链表是链表的一种,它有两个指针域:一个指向前一个结点,一个指向后一个结点。每个结点包含两个部分:数据和指针域,指针域分别指向前一个结点和后一个结点,所以每个结点都是由数据和两个指针域构成的。

双向链表的作用?

双向链表可以支持O(1)时间复杂度的在任何一个结点前或后插入一个结点。

双向链表的实现方式?

在C语言中,双向链表可以通过结构体和指针来实现,我们使用struct定义每个链表结点,包含数据和两个指针域。通过指针来连接每个结点形成链表,指针可以动态的指向前后结点,实现双向遍历。

创建双向链表

初始化一个双向链表

struct Node {
    int data;
    struct Node* next;
    struct Node* prev;
};

// 初始化一个空的双向链表
struct Node* linkedlist_init() {
    struct Node* head = (struct Node*) malloc(sizeof(struct Node));
    head->data = 0;
    head->next = NULL;
    head->prev = NULL;
    return head;
}

向双向链表中插入一个结点

// 在双向链表的pos位置增加一个节点node
void linkedlist_insert(struct Node* pos, struct Node* node) {
    node->next = pos->next;
    pos->next->prev = node;
    node->prev = pos;
    pos->next = node;
}

从双向链表中删除一个结点

// 从双向链表中删除一个节点
void linkedlist_delete(struct Node* node) {
    node->prev->next = node->next;
    node->next->prev = node->prev;
    free(node);
}

示例

示例1

以下示例展示了如何创建一个双向链表,并在其中插入3个结点,再删除第2个结点。

int main(void) {
    struct Node* head = linkedlist_init();
    struct Node* node1 = (struct Node*) malloc(sizeof(struct Node));
    struct Node* node2 = (struct Node*) malloc(sizeof(struct Node));
    struct Node* node3 = (struct Node*) malloc(sizeof(struct Node));

    node1->data = 1;
    node2->data = 2;
    node3->data = 3;

    linkedlist_insert(head, node1); // head->node1
    linkedlist_insert(node1, node2); // head->node1->node2
    linkedlist_insert(node2, node3); // head->node1->node2->node3

    linkedlist_delete(node2); // head->node1->node3

    return 0;
}

示例2

以下示例展示了如何遍历一个双向链表,分别从头、尾、中间向前、向后遍历链表。

int main(void) {
    // 创建一个双向链表并初始化
    struct Node* head = linkedlist_init();
    struct Node* node1 = (struct Node*) malloc(sizeof(struct Node));
    struct Node* node2 = (struct Node*) malloc(sizeof(struct Node));
    struct Node* node3 = (struct Node*) malloc(sizeof(struct Node));
    struct Node* node4 = (struct Node*) malloc(sizeof(struct Node));
    struct Node* node5 = (struct Node*) malloc(sizeof(struct Node));

    node1->data = 1;
    node2->data = 2;
    node3->data = 3;
    node4->data = 4;
    node5->data = 5;

    linkedlist_insert(head, node1); // head->node1
    linkedlist_insert(node1, node2); // head->node1->node2
    linkedlist_insert(node2, node3); // head->node1->node2->node3
    linkedlist_insert(node3, node4); // head->node1->node2->node3->node4
    linkedlist_insert(node4, node5); // head->node1->node2->node3->node4->node5


    // 从头开始向后遍历
    for (struct Node* p = head->next; p != NULL; p = p->next) {
        printf("%d ", p->data); // 1 2 3 4 5
    }
    printf("\n");

    // 从尾开始向前遍历
    for (struct Node* p = node5; p != NULL; p = p->prev) {
        printf("%d ", p->data); // 5 4 3 2 1
    }
    printf("\n");

    // 从中间开始向前遍历
    for (struct Node* p = node2->prev; p != NULL; p = p->prev) {
        printf("%d ", p->data); // 1
    }
    printf("\n");

    // 从中间开始向后遍历
    for (struct Node* p = node2; p != NULL; p = p->next) {
        printf("%d ", p->data); // 2 3 4 5
    }
    printf("\n");

    return 0;
}

总结

双向链表是一种非常实用的数据结构,在很多场景中都能够发挥巨大的作用。上述介绍的初始化、插入、删除等常用操作都是非常基础的操作,通过合理应用这些操作可以实现更加复杂、高效的数据处理。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言类的双向链表详解 - Python技术站

(0)
上一篇 2023年5月17日
下一篇 2023年5月17日

相关文章

  • Java数据结构之堆(优先队列)的实现

    Java 数据结构之堆(优先队列)的实现 什么是堆(优先队列) 堆(Heap)是一种数据结构,使用数组实现。堆分为小根堆和大根堆,大根堆满足父节点值大于子节点,小根堆则相反。堆通常被用来实现优先队列(Priority Queue)。 优先队列(Priority Queue)是一个能够让用户迅速查找到队列中最小值(或最大值)的抽象数据类型(ADT)。优先队列通…

    数据结构 2023年5月17日
    00
  • Codeforces Round 866 (Div. 2)

    A. Yura’s New Name 题意: 给出一个仅由_或^组成的字符串,你可以在任意位置添加_或^字符,使得字符串满足:任意字符要么属于^_^的一部分,要么属于^^的一部分。求最少添加的字符数量。 分析: 对于_我们只需处理没有组成^_^的_: ①如果_在首位置且左边没有^则添加^ ②如果_在尾位置且右边没有^则添加^ ③如果_在中间部分且右边没有^则…

    算法与数据结构 2023年4月25日
    00
  • Java数据结构之图(动力节点Java学院整理)

    Java数据结构之图是动力节点Java学院整理的一篇关于图的攻略教程,该教程包含以下主要内容: 一、图的定义 图是由若干个顶点以及它们之间的相互关系所构成的数学模型。它包含了许多实际生活中的应用,如社交网络、地图、电子邮件网络等。 二、图的存储方式 图的存储方式有两种:邻接矩阵和邻接表。 邻接矩阵 邻接矩阵以二维数组的形式存储图。对于有n个顶点的图,其邻接矩…

    数据结构 2023年5月17日
    00
  • 数据结构 C语言实现循环单链表的实例

    首先,在开始讲解数据结构中循环单链表的实现前,需要明确循环单链表的概念以及其与单链表的区别。 循环单链表是一种链式存储结构,与单链表不同的是,在循环单链表的尾部也可以指向链表的头部,形成一个环。因此,我们可以通过尾部的指针来遍历整个循环单链表。 接下来,为了方便理解和学习,我们将使用C语言来实现循环单链表的实例。下面分几个步骤来讲解。 1. 定义结构体和创建…

    数据结构 2023年5月17日
    00
  • C语言线性表顺序存储结构实例详解

    C语言线性表顺序存储结构实例详解 线性表的定义 线性表是数据结构中最基本的结构之一。它们是由相同数据类型的一组数据元素组成的序列。线性表具有唯一的首元素和唯一的末元素,除第一个元素之外的每个元素都有唯一的前继,除最后一个元素之外的每个元素都有唯一的后继。 线性表的存储方式 线性表有两种存储方式: 顺序存储和链式存储。 顺序存储采用一段连续的内存空间来存储线性…

    数据结构 2023年5月17日
    00
  • Java 数据结构链表操作实现代码

    下面是关于“Java 数据结构链表操作实现代码”的完整攻略。 1.链表实现原理 链表是一种经典的数据结构,其主要原理是通过指针将一系列节点连接起来。链表中的节点包含两个部分,一个是数据域,用于存放数据;另一个是指针域,用于指向下一个节点的位置。链表的头结点指向链表的第一个节点,最后一个节点的指针指向空。 2.链表的基本操作 链表的基本操作包括创建链表、插入节…

    数据结构 2023年5月17日
    00
  • C语言数据结构实现链表逆序并输出

    下面是C语言数据结构实现链表逆序并输出的完整攻略。 1. 题目分析 本题目要求实现对链表的逆序,并依次输出各节点的值。而链表的逆序可以通过改变各节点之间的连接方式来实现。 2. 思路分析 创建一个指针,指向原链表的头结点。 遍历链表,将每个节点的next指针指向它前面的节点,从而实现链表的逆序。 遍历逆序后的链表,从头结点开始,依次输出每个节点的值。 3. …

    数据结构 2023年5月17日
    00
  • Java数据结构之最小堆和最大堆的原理及实现详解

    Java数据结构之最小堆和最大堆的原理及实现详解 什么是堆? 堆是一种特殊的树形数据结构,它满足以下两个条件: 堆是一个完全二叉树,即除了最后一层,其他层都必须填满,最后一层从左到右填满 堆中每个节点的值必须满足某种特定的条件,例如最小堆要求每个节点的值都小于等于其子节点的值。 堆一般分为两种类型:最小堆和最大堆。 最小堆:每个节点的值都小于等于其子节点的值…

    数据结构 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部