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

yizhihongxing

作为本网站的作者,我很高兴为你讲解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日

相关文章

  • LCA——ST表+欧拉序

    了解到一个quan新的东西: 用ST表(欧拉序)实现LCA(树上最近公共祖先) 欧拉序 前序遍历得到的序列,叫dfs序但数字可以重复出现,一进一出,叫欧拉序会发现根结点总在中间而根结点是该段序列深度最小的点因此两个点的LCA,就是在该序列上两个点第一次出现的区间内深度最小的那个点 即转化为区间RMQ问题,可以用ST表当然你可以再写一棵线段树(如果有修改操作)…

    算法与数据结构 2023年5月4日
    00
  • C#数据结构与算法揭秘二 线性结构

    C#数据结构与算法揭秘二 线性结构 线性结构是指数据元素之间一对一的关系,即数据元素之间存在一个前驱和一个后继。一般有两种基本形式:线性表和栈、队列。 线性表 线性表是由同类型数据元素构成有序序列的线性结构,常被用于实现基于数组的数据结构,如向量、矩阵等。 线性表可以分为顺序表和链表两种。 顺序表(Sequence List):是把线性表的元素按照顺序存储在…

    数据结构 2023年5月17日
    00
  • Lua学习笔记之数据结构

    下面开始对”Lua学习笔记之数据结构”的完整攻略进行详细说明。 一、前言 在学习Lua时,数据结构是非常重要的一个方面,掌握了数据结构,就可以更好地编写Lua程序,提高程序的性能和可读性。本篇攻略主要介绍四种Lua数据结构:数组、表、字符串和函数,分别介绍其含义、特点、创建方法以及基本操作。 二、数组 2.1 数组的定义和创建 Lua中的数组是一种类似于C语…

    数据结构 2023年5月17日
    00
  • C语言数据结构之栈简单操作

    C语言数据结构之栈简单操作 什么是栈? 栈(Stack)是一种线性数据结构,它具有“后进先出”(Last-In-First-Out)的特性。栈顶是栈的一端,另一端称为栈底。每次只能从栈顶插入数据(入栈)或者从栈顶取出数据(出栈)。 栈的简单操作 栈的简单操作包括: 初始化栈 判断栈是否为空 判断栈是否已满 入栈操作 出栈操作 获取栈顶元素 栈的初始化 栈的初…

    数据结构 2023年5月16日
    00
  • Java链表数据结构及其简单使用方法解析

    Java链表数据结构及其简单使用方法解析 概述 链表是一种非线性结构,由一系列节点按照顺序连接而成。每个节点由数据域和指针域组成,数据域用于存储数据,指针域用于指向下一个节点或者上一个节点。在Java中,链表有多种实现方式,常见的有单向链表、双向链表等。 单向链表的实现 以下是一个单向链表的实现代码示例: public class Node { privat…

    数据结构 2023年5月17日
    00
  • java数据结构基础:算法

    Java数据结构基础:算法攻略 概述 在程序员的日常开发中,算法是一项重要的技能,而数据结构则是算法不可缺少的基础。本文将讲解Java数据结构中的基本算法,包括常见算法的实现,算法的分析及算法的运用。经过本文的学习,读者可以掌握Java中基础的算法实现及应用。 常见算法实现 排序算法 排序算法是算法中最基础的一类,常用的算法有冒泡排序、插入排序、选择排序、快…

    数据结构 2023年5月17日
    00
  • 一些常见的字符串匹配算法

    作者:京东零售 李文涛 一、简介 1.1 Background 字符串匹配在文本处理的广泛领域中是一个非常重要的主题。字符串匹配包括在文本中找到一个,或者更一般地说,所有字符串(通常来讲称其为模式)的出现。该模式表示为p=p[0..m-1];它的长度等于m。文本表示为t=t[0..n-1],它的长度等于n。两个字符串都建立在一个有限的字符集上。 一个比较常见…

    算法与数据结构 2023年4月25日
    00
  • 考研数据结构模板:顺序表、链表、栈、队列

    考研数据结构模板:顺序表、链表、栈、队列 前言 代码风格偏向于考研风格而非算法竞赛风格。 代码实现参考《2024数据结构王道复习指导》。 注释详细、保证看懂。 下面是已实现的数据结构模板: 顺序表SeqList 链表LinkList 双链表DLinkList 顺序栈SeqStack 循环顺序队列CircleQueue 链队列LinkQueue 顺序表SeqL…

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