C语言实现双向链表

yizhihongxing

C语言实现双向链表

简介

双向链表(Doubly Linked List)是一种常用的数据结构,其特点是每个节点既包含指向前驱节点的指针,也包含指向后继节点的指针。相比单向链表,它可以实现双向遍历,删除指定节点时无需遍历整个链表,提高了效率。

本文将详细介绍如何使用C语言实现双向链表。

实现步骤

  1. 定义节点结构体

    双向链表每个节点包含三个成员变量:数据域、指向前驱节点的指针、指向后继节点的指针。因此,我们首先需要定义一个节点结构体。

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

    其中,data表示该节点存储的数据,prev表示指向前驱节点的指针,next表示指向后继节点的指针。

  2. 定义链表结构体

    链表结构体包含两个指针变量:指向头节点和尾节点的指针。初始化时,头节点和尾节点均为NULL

    typedef struct List {
    Node *head;
    Node *tail;
    } List;

  3. 定义链表操作函数

    • createNode(int data):创建新节点,并返回指向该节点的指针。

      Node *createNode(int data) {
      Node *node = (Node*)malloc(sizeof(Node));
      node->data = data;
      node->prev = NULL;
      node->next = NULL;
      return node;
      }

    • insertNode(List *list, Node *node, int data):在指定节点之后插入新节点。

      void insertNode(List *list, Node *node, int data) {
      Node *newNode = createNode(data);
      newNode->prev = node;
      newNode->next = node->next;
      if (node->next == NULL) {
      list->tail = newNode;
      } else {
      node->next->prev = newNode;
      }
      node->next = newNode;
      }

    • deleteNode(List *list, Node *node):删除指定节点。

      void deleteNode(List *list, Node *node) {
      if (node->prev == NULL) {
      list->head = node->next;
      } else {
      node->prev->next = node->next;
      }
      if (node->next == NULL) {
      list->tail = node->prev;
      } else {
      node->next->prev = node->prev;
      }
      free(node);
      }

    • traverse(List *list):遍历整个链表,输出各个节点的数据。

      void traverse(List *list) {
      Node *node = list->head;
      while (node != NULL) {
      printf("%d ", node->data);
      node = node->next;
      }
      printf("\n");
      }

  4. 完整代码示例

    ```

    include

    include

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

    typedef struct List {
    Node head;
    Node
    tail;
    } List;

    Node createNode(int data) {
    Node
    node = (Node*)malloc(sizeof(Node));
    node->data = data;
    node->prev = NULL;
    node->next = NULL;
    return node;
    }

    void insertNode(List list, Node node, int data) {
    Node *newNode = createNode(data);
    newNode->prev = node;
    newNode->next = node->next;
    if (node->next == NULL) {
    list->tail = newNode;
    } else {
    node->next->prev = newNode;
    }
    node->next = newNode;
    }

    void deleteNode(List list, Node node) {
    if (node->prev == NULL) {
    list->head = node->next;
    } else {
    node->prev->next = node->next;
    }
    if (node->next == NULL) {
    list->tail = node->prev;
    } else {
    node->next->prev = node->prev;
    }
    free(node);
    }

    void traverse(List list) {
    Node
    node = list->head;
    while (node != NULL) {
    printf("%d ", node->data);
    node = node->next;
    }
    printf("\n");
    }

    int main() {
    List list = (List)malloc(sizeof(List));
    list->head = NULL;
    list->tail = NULL;

    Node *node1 = createNode(1);
    list->head = node1;
    list->tail = node1;
    
    Node *node2 = createNode(2);
    insertNode(list, node1, 2);
    
    Node *node3 = createNode(3);
    insertNode(list, node2, 3);
    
    deleteNode(list, node2);
    
    traverse(list);
    

    }
    ```

    程序执行结果为:

    1 3

    其中,先创建一个新链表,然后添加了3个节点(数据分别为1、2、3),然后删除了第二个节点,最后输出整个链表。可以看到,最终链表仅有两个节点(数据分别为1、3),并且能够成功进行双向遍历。

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

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

相关文章

  • 如何查看苹果手机内存多大 苹果64g内存够用吗

    如何查看苹果手机内存大小 苹果手机的内存大小可以通过以下步骤进行查看: 打开手机的设置应用程序。 在设置菜单中,向下滚动并点击“通用”选项。 在通用菜单中,继续向下滚动并点击“关于本机”选项。 在关于本机菜单中,您将看到“容量”或“内存”一栏,显示您的手机的内存大小。 示例说明1:假设您的苹果手机是iPhone 12,您可以按照以下步骤查看其内存大小:1. …

    other 2023年8月2日
    00
  • asp.net AjaxControlToolKit–TabContainer控件的介绍

    我可以为您提供详细讲解“ASP.NET AjaxControlToolkit–TabContainer控件的介绍”的攻略。 介绍 ASP.NET AjaxControlToolkit–TabContainer控件是一种可用于创建带有选项卡式用户界面的控件。TabContainer控件允许在单个页面中组织和呈现不同的内容。这对于使网页更加易于管理和导航非常…

    other 2023年6月27日
    00
  • c++动态内存空间示例(自定义空间类型大小和空间长度)

    C++动态内存空间示例(自定义空间类型大小和空间长度) 在C++中,我们可以使用动态内存分配来创建自定义大小和长度的内存空间。这可以通过使用new和delete运算符来实现。下面是一个完整的攻略,包含两个示例说明。 示例1:动态分配整型数组 #include <iostream> int main() { int length; // 获取用户输…

    other 2023年7月31日
    00
  • MySQL更新存放JSON的字段、\“ 转义成 “的问题描述

    MySQL中可以使用UPDATE语句更新存放JSON的字段。JSON是一种轻量级的数据交换格式,常常用于表示复杂的数据结构。当我们需要更新JSON字段中的值时,可以使用MySQL提供的一些内置函数来实现。 在更新JSON字段时,有时候需要使用到双引号。而MySQL中默认的转义字符是反斜杠(\),所以需要使用双反斜杠(\)来转义双引号。 下面是一个具体的示例,…

    other 2023年6月25日
    00
  • Java基于socket实现的客户端和服务端通信功能完整实例

    Java基于socket实现的客户端和服务端通信功能完整实例 什么是Socket Socket是一个抽象的概念,可以理解为“插座”,在计算机网络中,两个程序通过Socket在网络上互相通信。Socket提供了程序与网络之间的通信接口。 Java中的Socket Java的Socket是基于TCP/IP协议实现的。在Java中,可以通过Socket类和Serv…

    other 2023年6月25日
    00
  • pcap文件格式解析

    pcap文件格式解析 Pcap文件格式是网络数据包捕获的标准格式,目前广泛应用于网络协议分析、网络攻击检测等领域。本文将具体介绍Pcap文件格式,以及如何解析Pcap文件。 Pcap文件格式 Pcap文件格式由Pcap全称Packet Capture。其包含两部分:文件头(Global Header)和数据包内容(Packet Data)。文件头部分包括了P…

    其他 2023年3月28日
    00
  • PHP Global定义全局变量使用说明

    PHP Global定义全局变量使用说明 在PHP中,全局变量是在脚本的任何地方都可以访问的变量。使用全局变量可以在不同的函数和类中共享数据。在本攻略中,我们将详细讲解如何定义和使用全局变量。 定义全局变量 要定义一个全局变量,我们需要使用global关键字。这将告诉PHP解释器该变量是全局的,可以在脚本的任何地方访问。 下面是定义全局变量的语法: glob…

    other 2023年7月28日
    00
  • win10电脑频繁蓝屏重启怎么解决?

    Win10电脑频繁蓝屏重启问题解决攻略 背景描述 频繁蓝屏重启是 Win10 电脑常见的一个问题。当电脑出现频繁蓝屏重启时,不仅会造成数据丢失,还会影响到我们的正常使用,因此需要我们及时解决这个问题。本文将会从多方面入手,详细讲解 Win10 电脑频繁蓝屏重启怎么解决。 解决方案 1. 更新系统补丁 Win10 系统经常会发布补丁来修复一些已知问题,因此我们…

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