C语言数据结构 双向链表的建立与基本操作

C语言数据结构 双向链表的建立与基本操作

双向链表的定义

双向链表是一种常见的线性数据结构,它由多个结点组成,每个结点有两个指针,一个指向前一个结点,一个指向后一个结点。对于一个双向链表,我们可以获得其第一个结点和最后一个结点的指针,也可以沿着链表从前往后或从后往前遍历链表的每个结点。

双向链表的建立

我们首先需要定义一个双向链表的结点类型,包括两个指针,一个表示前一个结点,一个表示后一个结点。如下所示:

typedef struct node {
    int data;
    struct node *prev;  // 指向前一个结点
    struct node *next;  // 指向后一个结点
} Node;

然后,我们可以声明一个头结点,作为链表的头部,方便插入和删除操作。头结点不存储数据,只是一个指针类型的变量,其 prev 指针和 next 指针都指向 NULL,如下所示:

Node *head = (Node *)malloc(sizeof(Node));
head->prev = NULL;
head->next = NULL;

上述操作会创建一个空的双向链表,头结点为 head。

接下来,我们可以通过插入操作,逐个将结点插入到链表中,从而创建出一个完整的双向链表。在插入操作中,需要注意后继结点的指针应该指向新插入的结点,前驱结点的指针应该指向新插入的结点,新插入的结点的前驱结点指针应该指向前驱结点。

双向链表的基本操作

插入操作

双向链表的插入操作与单链表的插入操作类似,需要指定插入的位置和插入的值。如果插入的位置是链表的头部,则需要修改头结点的 next 指针,如果插入的位置是链表的中间或尾部,则需要修改插入结点前驱结点和后继结点的指针。代码示例如下:

void insert(Node *head, int pos, int value) {
    Node *newNode = (Node *)malloc(sizeof(Node));
    newNode->data = value;
    Node *p = head;

    for (int i = 0; i < pos && p != NULL; i++) {
        p = p->next;
    }

    if (p == NULL) {
        return;  // 位置错误,不插入结点
    }

    newNode->prev = p->prev;
    newNode->next = p;
    p->prev->next = newNode;
    p->prev = newNode;
}

删除操作

双向链表的删除操作与插入操作类似,同样需要指定删除的位置。删除操作需要修改删除结点前驱结点和后继结点的指针,代码示例如下:

void delete(Node *head, int pos) {
    Node *p = head;

    for (int i = 0; i < pos && p != NULL; i++) {
        p = p->next;
    }

    if (p == NULL) {
        return;  // 位置错误,不删除结点
    }

    p->prev->next = p->next;
    p->next->prev = p->prev;
    free(p);
}

遍历操作

双向链表的遍历操作可以从头结点开始遍历,依次访问每一个结点,并将其数据打印出来。代码示例如下:

void traverse(Node *head) {
    Node *p = head->next;

    while (p != NULL) {
        printf("%d ", p->data);
        p = p->next;
    }
}

示例说明

示例一

以下代码演示如何构建一个双向链表,插入若干数据并从头到尾输出链表:

#include <stdio.h>
#include <stdlib.h>

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

void insert(Node *head, int pos, int value) {
    Node *newNode = (Node *)malloc(sizeof(Node));
    newNode->data = value;
    Node *p = head;

    for (int i = 0; i < pos && p != NULL; i++) {
        p = p->next;
    }

    if (p == NULL) {
        return;  // 位置错误,不插入结点
    }

    newNode->prev = p->prev;
    newNode->next = p;
    p->prev->next = newNode;
    p->prev = newNode;
}

void traverse(Node *head) {
    Node *p = head->next;

    while (p != NULL) {
        printf("%d ", p->data);
        p = p->next;
    }
}

int main() {
    Node *head = (Node *)malloc(sizeof(Node));
    head->prev = NULL;
    head->next = NULL;

    insert(head, 0, 1);
    insert(head, 1, 2);
    insert(head, 2, 3);
    insert(head, 3, 4);

    traverse(head);
    return 0;
}

上述代码将输出:1 2 3 4

示例二

以下代码演示如何构建一个双向链表,删除链表中的某个结点并从头到尾输出链表:

#include <stdio.h>
#include <stdlib.h>

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

void delete(Node *head, int pos) {
    Node *p = head;

    for (int i = 0; i < pos && p != NULL; i++) {
        p = p->next;
    }

    if (p == NULL) {
        return;  // 位置错误,不删除结点
    }

    p->prev->next = p->next;
    p->next->prev = p->prev;
    free(p);
}

void traverse(Node *head) {
    Node *p = head->next;

    while (p != NULL) {
        printf("%d ", p->data);
        p = p->next;
    }
}

int main() {
    Node *head = (Node *)malloc(sizeof(Node));
    head->prev = NULL;
    head->next = NULL;

    Node *node1 = (Node *)malloc(sizeof(Node));
    node1->data = 1;
    head->next = node1;
    node1->prev = head;
    node1->next = NULL;

    Node *node2 = (Node *)malloc(sizeof(Node));
    node2->data = 2;
    node1->next = node2;
    node2->prev = node1;
    node2->next = NULL;

    Node *node3 = (Node *)malloc(sizeof(Node));
    node3->data = 3;
    node2->next = node3;
    node3->prev = node2;
    node3->next = NULL;

    delete(head, 2);

    traverse(head);
    return 0;
}

上述代码将输出:1 2

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言数据结构 双向链表的建立与基本操作 - Python技术站

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

相关文章

  • C语言编程简单却重要的数据结构顺序表全面讲解

    C语言编程简单却重要的数据结构顺序表全面讲解 什么是顺序表? 顺序表是一种线性表,指的是一组有限元素的有限序列,其元素的逻辑顺序与它们在分配到的内存地址上的物理顺序相同或者等价。也就是说,顺序表中的元素按照其在内存中的位置依次存放。 顺序表的实现方式 顺序表的实现方式一般是使用数组,数组中的每一个元素对应着顺序表中的一个元素,位置相对应。 顺序表的优点 支持…

    数据结构 2023年5月17日
    00
  • 数据结构之哈夫曼树与哈夫曼编码

    一、背景 编码是信息处理的基础(重新表示信息)。 普通的编码是等长编码,例如7位的ASCIL编码,对出现频率不同的字符都使用相同的编码长度。但其在传输和存储等情况下编码效率不高。 可使用不等长编码,来压缩编码:高频字符编码长度更短,低频字符编码长度更长。   [例] 将百分制的考试成绩转换成五分制的成绩 按顺序分别编码。 按频率分别编码(高频短编码,类似于香…

    算法与数据结构 2023年4月17日
    00
  • 常用内核架构

      本文分享自天翼云开发者社区《常用内核架构》,作者:JackW   宏内核 应用程序调用内存分配的 API(应用程序接口)函数。 处理器切换到特权模式,开始运行内核代码。 内核里的内存管理代码按照特定的算法,分配一块内存。 把分配的内存块的首地址,返回给内存分配的 API 函数。 内存分配的 API 函数返回,处理器开始运行用户模式下的应用程序,应用程序就…

    算法与数据结构 2023年4月22日
    00
  • C#数据结构与算法揭秘四 双向链表

    C#数据结构与算法揭秘四 双向链表 简介 本文将讲解如何在C#中实现双向链表。双向链表是一种常用的数据结构,在许多算法中都有广泛应用,它提供了与单向链表不同的灵活性和便利性。 双向链表的实现 创建一个双向节点 双向链表由节点(Node)组成。一个节点包含两个指针:一个指向前一个节点,一个指向后一个节点。由于这两个指针都可能为null,所以我们将它们声明为可空…

    数据结构 2023年5月17日
    00
  • C语言实现数据结构迷宫实验

    C语言实现数据结构迷宫实验攻略 简介 迷宫是计算机图形学中的一个经典问题,也是数据结构和算法中常见的题目。C语言是一种广泛使用的编程语言,具有充分的编程接口和功能,可以方便地实现迷宫算法和数据结构。 本文将详细讲解C语言实现数据结构迷宫实验的完整攻略,让读者能够更加深入地理解迷宫算法和数据结构的应用。 实现步骤 1. 创建迷宫结构体 首先需要创建一个迷宫结构…

    数据结构 2023年5月17日
    00
  • Python内存管理器如何实现池化技术

    Python内存管理器使用了池化技术来进行内存管理,这使得Python程序的内存管理效率比较高。下面我将详细介绍Python内存管理器如何实现池化技术: 1. 内存分配 Python内存管理器在Python运行时,会维护多个大小不同的内存块池,每个池的大小相同。当Python程序需要分配内存时,会首先在池中寻找是否有剩余内存块可以分配。如果有,则分配给程序使…

    数据结构 2023年5月17日
    00
  • C语言结构体struct详解

    C语言结构体struct详解 什么是结构体? 在C语言中,结构体是一种用户自定义的数据类型,它可以将不同的数据类型组合在一起形成一个新的数据类型。结构体主要由结构体名、成员和符号构成。 使用结构体可以方便地定义一些复杂的数据类型,例如表示一个学生信息的数据类型,可以包括姓名、学号、性别、年龄等信息。 结构体的定义和声明 结构体的定义通常放在函数外部,以便在整…

    数据结构 2023年5月17日
    00
  • 一、对系统理论的认识

           经过一周的时间学习,我们知道了系统的定义:是一个由一组相互连接的要素构成的,能够实现某个目标的整体,任何一个系统都包括三种构成要件:要素连接,功能或目标。       1.系统的连接使得系统呈现特定的结构,使得系统的各个部件连接而产生系统特有的功能—相关性导新功能涌现。连接的媒介—“三流”(信息流,能量流,物质流)。       2.系统的静态…

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