C语言双向链表的原理与使用操作

C语言双向链表的原理与使用操作

什么是双向链表

双向链表是由一系列结点组成的数据结构,每个结点除了有指向下一个结点的指针,还有指向上一个结点的指针。这种链表可以从头到尾或者从尾到头进行遍历。

双向链表的结构

下面是一个双向链表的结构体定义:

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

其中data表示结点所存储的数据,prenext分别表示指向前一个结点和后一个结点的指针。

双向链表的操作

初始化

在创建双向链表之前需要先进行初始化,定义一个头节点指针,并将其指向NULL。代码如下:

node *head = NULL;

插入

双向链表的插入操作比较灵活,可以在任意位置插入。假设要在第二个结点的位置插入一个新的结点,代码如下:

node *new_node = (node *)malloc(sizeof(node));
new_node->data = 10;

node *temp = head->next;
head->next = new_node;
new_node->pre = head;
new_node->next = temp;
if (temp != NULL) {
    temp->pre = new_node;
}

首先先创建一个新的结点并赋值,然后将当前节点的后继赋值给新节点的后继,将新节点的前驱赋值为当前节点,将新节点连到当前节点的后面。

删除

双向链表的删除操作也比较灵活,同样可以删除任意位置的结点。假设要删除第二个结点,代码如下:

node *temp = head->next;
if (temp != NULL) {
    head->next = temp->next;
    if (temp->next != NULL) {
        temp->next->pre = head;
    }
    free(temp);
}

首先将当前节点的后继节点保存到临时变量中,然后修改当前节点的后继指向下一个节点,如果下一个节点存在,则将它的前驱指针修改为当前节点,最后释放掉被删除的节点。

示例

以下是一个简单的示例用来说明双向链表的使用操作:

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

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

void insert(node *head, int data);
void delete(node *head, int data);
void print(node *head);

int main() {
    node *head = (node *)malloc(sizeof(node));
    head->pre = NULL;
    head->next = NULL;

    insert(head, 10);
    insert(head, 20);
    insert(head, 30);
    insert(head, 40);
    insert(head, 50);

    delete(head, 30);

    print(head);

    // 释放节点
    node *temp;
    while (head != NULL) {
        temp = head;
        head = head->next;
        free(temp);
    }

    return 0;
}

void insert(node *head, int data) {
    node *new_node = (node *)malloc(sizeof(node));
    new_node->data = data;

    node *temp = head->next;
    head->next = new_node;
    new_node->pre = head;
    new_node->next = temp;
    if (temp != NULL) {
        temp->pre = new_node;
    }
}

void delete(node *head, int data) {
    node *temp = head->next;
    while (temp != NULL) {
        if (temp->data == data) {
            temp->pre->next = temp->next;
            if (temp->next != NULL) {
                temp->next->pre = temp->pre;
            }
            free(temp);
            return;
        }
        temp = temp->next;
    }
    printf("节点不存在\n");
}

void print(node *head) {
    node *temp = head->next;
    printf("链表内容:");
    while (temp != NULL) {
        printf("%d ", temp->data);
        temp = temp->next;
    }
    printf("\n");
}

运行结果:

链表内容:10 20 40 50 

以上就是C语言双向链表的原理与使用操作的完整攻略。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言双向链表的原理与使用操作 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • 虚拟路径…”映射到另一个应用程序,这是不允许的!

    “虚拟路径…映射到另一个应用程序,这是不允许的!”这是一种常见的错误提示,通常出现在ASP.NET应用程序中。这个错误提示的意思是说,您的ASP.NET应用程序试图在虚拟路径上创建一个与另一个ASP.NET应用程序相同的路径映射,这样会导致运行时冲突,因此被禁止。 这个错误往往是由于多个ASP.NET应用程序创建了相同的虚拟路径造成的。例如,您有两个AS…

    other 2023年6月25日
    00
  • Linux平台安装MongoDB及使用Docker安装MongoDB

    Linux平台安装MongoDB及使用Docker安装MongoDB 简介 MongoDB 是一个 NoSQL 数据库,它的灵活性、高效性使其成为互联网数据存储和查询的首选方案。MongoDB 具有良好的数据可扩展性,支持水平和垂直扩展。本文将介绍如何在 Linux 平台上安装 MongoDB 和使用 Docker 安装 MongoDB。 在 Linux 平…

    其他 2023年3月28日
    00
  • 魔兽世界7.3.5痛苦术怎么堆属性 wow7.35痛苦术配装属性优先级攻略

    魔兽世界7.3.5痛苦术属性堆叠攻略 介绍 在魔兽世界中,痛苦术是一个强大的术士专精,可以造成持续伤害并拥有一定的控制能力。为了在游戏中最大化痛苦术的输出效果,正确堆叠属性是至关重要的。 属性优先级 在选择配装方案时,我们需要根据属性的优先级来进行决策。以下是痛苦术属性的一般优先级,由高到低排列: 精通(Mastery):提高持续伤害的加成效果。 爆击(Cr…

    other 2023年6月28日
    00
  • 【实践】js封装jqsiblings方法

    【实践】js封装jqsiblings方法 前言 在日常开发中,我们可能需要获取某个元素的兄弟节点。但是,jQuery的siblings方法有时候不太满足我们的需求,毕竟它是针对jQuery对象的操作。因此,我们可以考虑使用JavaScript来实现一个更加灵活的兄弟节点获取方法。 实现思路 我们的实现思路是,通过获取当前节点的父节点,然后遍历父节点的所有子节…

    其他 2023年3月28日
    00
  • CAD怎么使用构造线? CAD构造线画法

    CAD(计算机辅助设计)是一种广泛应用于工程和设计领域的软件工具,用于创建和修改数字模型。在CAD中,构造线是一种用于辅助绘图和设计的特殊线型。下面是关于如何使用构造线以及CAD构造线画法的详细攻略: 使用构造线的目的 构造线在CAD中的主要目的是辅助绘图和设计过程。它们通常用于以下几个方面:1. 辅助定位:构造线可以用于确定几何图形的位置和方向,帮助用户精…

    other 2023年8月6日
    00
  • CSS2中从优先权重的计算方式来辨别下CSS

    CSS2 中,样式的优先权重是由选择器的特殊性(specificity)和源代码顺序(order)两者共同决定的。通过这个规则,我们可以区分不同优先级的 CSS 规则,并决定哪个样式优先应用。 选择器特殊性 每个选择器都有它自己的特殊性值,表示它的权重。特殊性值靠谱如下: 选择器中每个 ID 值为一个数,即 0, 1, 0, 0 选择器中每个 class 值…

    other 2023年6月27日
    00
  • 分配字节内存失败,请检查系统内存是否被耗尽?

    当你在使用计算机程序时,可能会遇到错误消息“分配字节内存失败,请检查系统内存是否被耗尽?”。这个错误消息通常表示你的计算机没有足够的可用内存来分配给程序使用。这可能是由于以下几个原因导致的: 系统内存不足:你的计算机可能没有足够的物理内存可供程序使用。这可能是因为你同时运行了太多的程序,导致系统内存被耗尽。解决这个问题的方法是关闭一些不必要的程序,以释放内存…

    other 2023年8月1日
    00
  • java中TCP实现回显服务器及客户端

    Java中TCP实现回显服务器及客户端的步骤如下: 1. 编写服务器端程序 服务器端需要完成以下任务: 创建ServerSocket对象 ServerSocket serverSocket = new ServerSocket(8888); 监听客户端的连接请求 Socket socket = serverSocket.accept(); 读取客户端发送的数…

    other 2023年6月27日
    00
合作推广
合作推广
分享本页
返回顶部