C数据结构之双链表详细示例分析

作为本网站的作者,我很高兴为你讲解C数据结构之双链表详细示例分析的完整攻略。

双链表简介与定义

双链表是链表的一种,在链表中每一个节点都有一个指针域,指向下一个节点,这个指针域称为next指针;而在双链表中每一个节点也有两个指针域,一个指向前驱节点,另一个指向后继节点,即prev指针与next指针。由于双链表存在两个指针域,因此它支持双向遍历,无论是正向还是反向遍历,都是很方便的。

在C语言中,我们可以采用结构体来定义双链表节点的数据类型,结构体中包含节点数据和两个指针域,定义如下:

struct DListNode {
    int val;
    struct DListNode *prev, *next;
};

其中,val表示双链表节点存储的数据,prev指针域表示指向前驱节点的指针,next指针域表示指向后继节点的指针。

双链表基本操作

双链表的基本操作包括插入节点、删除节点、查找节点和遍历节点等。下面我们介绍这些操作的具体实现。

插入节点

双链表中插入一个节点需要分三步操作:

  1. 创建一个新节点
  2. 将新节点的next指针指向原链表中当前位置下一个节点(插入在链表中间或尾部)或者指向NULL(插入在链表头部或空链表)
  3. 将新节点的prev指针指向原链表中当前位置的前一个节点(插入在链表中间或头部)或者指向NULL(插入在链表尾部或空链表)

以下是一个示例代码:

void DListInsert(struct DListNode **head, struct DListNode *node, int pos) {
    if (pos < 1) pos = 1;
    if (!*head) {
        *head = node;
        return;
    }
    if (pos == 1) {
        node->next = *head;
        (*head)->prev = node;
        *head = node;
        return;
    }
    struct DListNode *p = *head;
    for (int i = 2; i < pos && p->next; i++) p = p->next;
    node->next = p->next;
    p->next = node;
    node->prev = p;
    if (node->next) node->next->prev = node;
}

上述代码实现了指定位置插入元素的操作,并考虑了空链表和插入头节点的情况。

删除节点

双链表中删除一个节点需要分两步操作:

  1. 修改被删除节点前驱节点的next指针,使其指向被删除节点的后继节点
  2. 修改被删除节点的后继节点的prev指针,使其指向被删除节点的前驱节点

以下是一个示例代码:

void DListDelete(struct DListNode **head, int val) {
    struct DListNode *p = *head;
    while (p && p->val != val) p = p->next;
    if (p) {
        if (p->prev) p->prev->next = p->next;
        else *head = p->next;
        if (p->next) p->next->prev = p->prev;
        free(p);
    }
}

上述代码实现了删除指定元素的操作,并考虑了被删除元素是头节点的情况。

查找节点

对于双链表查找指定元素,我们可以用遍历的方式逐个比较节点的元素值。以下是一个示例代码:

struct DListNode *DListFind(struct DListNode *head, int val) {
    struct DListNode *p = head;
    while (p && p->val != val) p = p->next;
    return p;
}

遍历节点

双链表的遍历可以使用指针移动实现。以下是一个示例代码:

void DListTraverse(struct DListNode *head) {
    struct DListNode *p = head;
    while (p) {
        printf("%d ", p->val);
        p = p->next;
    }
    printf("\n");
}

示例说明

示例一:双向链表的构建

int main() {
    struct DListNode *head = NULL;
    int a[] = {1, 2, 3, 4, 5};
    int n = sizeof(a) / sizeof(int);
    for (int i = 0; i < n; i++)
        DListInsert(&head, GetNewDListNode(a[i]), i + 1);
    DListTraverse(head);
    return 0;
}

上述代码中,我们首先定义双链表头节点为NULL,然后插入1,2,3,4,5五个元素到双链表中,并使用DListTraverse函数遍历节点。输出结果应该为:

1 2 3 4 5

示例二:双向链表的删除操作

int main() {
    struct DListNode *head = NULL;
    int a[] = {1, 2, 3, 4, 5};
    int n = sizeof(a) / sizeof(int);
    for (int i = 0; i < n; i++)
        DListInsert(&head, GetNewDListNode(a[i]), i + 1);
    DListTraverse(head);
    DListDelete(&head, 3);
    DListDelete(&head, 1);
    DListTraverse(head);
    return 0;
}

上述代码中,我们首先定义双链表头节点为NULL,然后插入1,2,3,4,5五个元素到双链表中。接着使用DListTraverse函数遍历双链表,输出结果应该为:

1 2 3 4 5

然后,我们使用DListDelete函数依次删除元素3以及元素1,并使用DListTraverse再次遍历双链表,输出结果应该为:

2 4 5

总结

本篇文章中,我们讲解了C数据结构之双链表的基本定义及常见操作,包括插入节点、删除节点、查找节点和遍历节点等。我们还使用了两个示例说明双链表的构建和删除两个操作。希望这篇文章能对大家有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C数据结构之双链表详细示例分析 - Python技术站

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

相关文章

  • Go语言数据结构之选择排序示例详解

    Go语言数据结构之选择排序示例详解 什么是选择排序? 选择排序是一种简单的排序算法,它的基本思想是在待排序的数列中选择一个最小(或最大)的元素放到最前面,再在剩下的数列中选择一个最小(或最大)的元素放到已排序序列的末尾,以此类推,直到所有的元素都排序完毕。 其排序的时间复杂度为O(N²),在数据量较小的情况下使用起来非常方便。 选择排序的实现 下面我们来看一…

    数据结构 2023年5月17日
    00
  • C语言数据结构旋转链表的实现

    C语言数据结构旋转链表的实现 1. 什么是旋转链表 旋转链表是一种特殊的链表,其特点是将链表的最后一个节点移动到最前面,形成一个环形链表的效果。比如下面这个链表: 1 -> 2 -> 3 -> 4 -> 5 经过一次旋转之后变成了: 5 -> 1 -> 2 -> 3 -> 4 2. 实现思路 旋转链表的实现思路…

    数据结构 2023年5月17日
    00
  • C++抽象数据类型介绍

    C++抽象数据类型介绍 什么是抽象数据类型? 抽象数据类型(Abstract Data Type,ADT),是数据类型的一个数学模型。它实现了数据类型的抽象过程,将数据与操作分离,使得操作具有独立性,而数据只作为函数参数和返回值存在。 举个例子,ADT可以定义一个栈(Stack),栈的实现需要以下操作: 初始化栈 压入数据 弹出数据 获取栈顶数据 检查栈是否…

    数据结构 2023年5月17日
    00
  • 多维度深入分析Redis的5种基本数据结构

    多维度深入分析Redis的5种基本数据结构 Redis是一种高性能、内存数据存储系统,它支持多种数据结构,包括字符串、哈希表、列表、集合和有序集合。其中,每种数据结构都具有不同的特性和用途,本文将对这五种基本数据结构进行深入分析。 1. 字符串(string) 字符串是最基本的数据结构,一个字符串可以存储任意二进制数据,例如一个jpg图片或者一个序列化的对象…

    数据结构 2023年5月17日
    00
  • Java数据结构的十大排序

    Java数据结构的十大排序攻略 简介 在计算机科学中,排序算法是一种将一串数据按照特定顺序进行排列的方法,其中常见的排序算法有很多种,不同的算法适用于不同的数据类型和数据规模。Java是一种常见的编程语言,也提供了很多实现排序算法的类和方法。 本文将介绍Java数据结构的十大排序算法,分别为:插入排序、希尔排序、选择排序、冒泡排序、快速排序、归并排序、堆排序…

    数据结构 2023年5月17日
    00
  • C++中的数组、链表与哈希表

    C++中的数组、链表与哈希表 数组 数组是一种数据结构,它存储的是一组相同类型的值。数组中每个元素的类型都是相同的,而且数组中的元素是按照一定的顺序排列的。C++中的数组是有序的,并且可以通过下标来访问数组中的元素。 数组的定义和初始化 在C++中定义数组的语法如下: type arr_name[arr_size]; 其中,type表示数组元素的类型,arr…

    数据结构 2023年5月17日
    00
  • 算法总结–ST表

    声明(叠甲):鄙人水平有限,本文为作者的学习总结,仅供参考。 1. RMQ 介绍 在开始介绍 ST 表前,我们先了解以下它以用的场景 RMQ问题 。RMQ (Range Minimum/Maximum Query)问题是指:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在i,j里的最小(大)值,也就是说,RMQ…

    算法与数据结构 2023年4月18日
    00
  • 数据结构C语言链表的实现介绍

    数据结构C语言链表的实现介绍 1. 什么是链表? 链表是一种常见的数据结构,它由一系列的节点(Node)通过链接(Link)组成,每个节点包含两个部分:数据域(Data)和指针(Pointer),数据域用来存储数据,指针用来链接下一个节点。链表最重要的优点就是支持动态扩展,占用内存比较灵活,相比于数组,链表在增加和删除元素时更加高效。 2. 链表的实现 链表…

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