C++双向链表的增删查改操作方法讲解

关于C++双向链表的增删查改操作方法,一般可以分为以下几步:

第一步:定义链表结构体

我们都知道链表是一种动态数据结构,它的每个元素都包含指向前一个元素和后一个元素的指针。因此,在C++中,我们可以用结构体来定义一个链表节点,具体的定义如下:

struct ListNode {
    int val;
    ListNode* prev;
    ListNode* next;
    ListNode(int x) : val(x), prev(nullptr), next(nullptr) {}
};

其中,val是节点的值,prev和next分别指向前一个节点和后一个节点。在这里,我们使用nullptr来初始化指针。

第二步:实现链表的增加操作

链表的增加操作也可以分为头插和尾插两种方式。

头插法

头插法是将新节点插入到链表的头部。具体的实现如下:

void addAtHead(ListNode*& head, int val) {
     ListNode* node = new ListNode(val);
     if (!head) {
         head = node;
     } else {
         node->next = head;
         head->prev = node;
         head = node;
     }
}

第一行代码是创建一个新的节点。如果链表为空,则将这个新节点设置为头节点。如果链表不为空,则将这个新节点插入到头节点的前面,并更新头节点的信息。

尾插法

尾插法是将新节点插入到链表的尾部。具体的实现如下:

void addAtTail(ListNode*& head, int val) {
    ListNode* node = new ListNode(val);
    if (!head) {
        head = node;
    } else {
        ListNode* cur = head;
        while (cur->next) {
            cur = cur->next;
        }
        cur->next = node;
        node->prev = cur;
    }
}

第一行代码同样是创建一个新的节点。如果链表为空,则将这个新节点设置为头节点。如果链表不为空,则从头节点开始遍历到链表尾部,在尾节点的后面加入一个新节点。

第三步:实现链表的删除操作

链表的删除操作也可以分为删除头节点和删除尾节点两种方式。

删除头节点

删除头节点可以直接将头节点的后一个节点作为头节点,并释放原头节点的内存空间。具体的实现如下:

void deleteAtHead(ListNode*& head) {
    if (!head) {
        return;
    }
    ListNode* tmp = head;
    head = head->next;
    if (head) {
        head->prev = nullptr;
    }
    delete tmp;
}

如果链表不为空,则将头节点指针指向第二个节点。由于新的头节点的前面没有节点,因此将它的prev指针置空。最后,释放掉原来的头节点的内存空间。

删除尾节点

删除尾节点可以遍历到尾节点的前一个节点,并将它的next指针置空。然后,释放掉原尾节点的内存空间。具体的实现如下:

void deleteAtTail(ListNode*& head) {
    if (!head) {
        return;
    }
    if (!head->next) {
        delete head;
        head = nullptr;
        return;
    }
    ListNode* cur = head;
    while (cur->next) {
        cur = cur->next;
    }
    cur->prev->next = nullptr;
    delete cur;
}

如果链表只有一个节点,直接释放掉这个节点并将头指针置空。否则从头节点开始遍历到尾节点的前一个节点,并释放掉尾节点的内存空间。

第四步:实现链表的查找操作

链表的查找操作主要是根据节点的值进行查找。我们可以从头节点开始遍历每个节点,如果找到了对应的节点,则返回该节点的指针。否则,返回nullptr。具体的实现如下:

ListNode* search(ListNode* head, int val) {
    while (head) {
        if (head->val == val) {
            return head;
        }
        head = head->next;
    }
    return nullptr;
}

从头节点开始遍历每个节点,如果找到了节点的值等于val,则返回该节点的指针。否则,继续向后遍历,直到链表的末尾都没有找到节点,则返回nullptr。

第五步:实现链表的修改操作

修改链表中的节点可以直接通过访问节点的val来修改。具体的实现如下:

void update(ListNode* head, int oldVal, int newVal) {
    ListNode* node = search(head, oldVal);
    if (node) {
        node->val = newVal;
    }
}

从头节点开始查找节点的值等于oldVal的节点。如果找到了节点,则将该节点的值修改为newVal。

示例说明

示例一

通过头插法构建一个链表,并输出该链表的值。

ListNode* head = nullptr;
addAtHead(head, 1);
addAtHead(head, 2); 
addAtHead(head, 3); 

ListNode* cur = head;
while (cur) {
    cout << cur->val << " ";
    cur = cur->next;
}

输出结果为“3 2 1”。

示例二

通过尾插法构建一个链表,并删除尾节点。

ListNode* head = nullptr;
addAtTail(head, 1);
addAtTail(head, 2); 
addAtTail(head, 3); 

deleteAtTail(head);

ListNode* cur = head;
while (cur) {
    cout << cur->val << " ";
    cur = cur->next;
}

输出结果为“1 2”。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++双向链表的增删查改操作方法讲解 - Python技术站

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

相关文章

  • 没有竞品 紫光展锐推出超强算力AIoT解决方案 V5663

    紫光展锐推出超强算力AIoT解决方案 V5663 最近,紫光展锐推出了一款超强算力AIoT解决方案 V5663,不仅拥有高性能、高效率的特点,而且具备可塑性强、广泛适用的特点。以下是详细的攻略,希望对您有所帮助。 什么是V5663? V5663是紫光展锐推出的一款集成了高性能CPU、GPU和AI加速器的AIoT解决方案,可以用于物联网、智能制造、智能家居等多…

    other 2023年6月26日
    00
  • uiautomator2使用教程

    uiautomator2使用教程 什么是uiautomator2 uiautomator是Google提供的一个测试框架,可以用于Android设备的自动化测试。uiautomator2是在uiautomator的基础上进行的二次开发,更加稳定和易用。 uiautomator2的特点: 大众化:uiautomator2只需要在root的设备上安装一个apk,…

    其他 2023年3月28日
    00
  • div嵌套div布局

    div嵌套div布局 在Web开发中,div元素是一种非常常用的布局元素。通过嵌套div元素,可以实现复杂布局效果。本文介绍如何使用div嵌套div实现布局,并提供两个示例说明。 基本语法 div元素是一个块级元素,可以用于创建容器。通过嵌套div元素,可以实现复杂的布局效果。以下是一个基本的div嵌套div的示例: <div class="…

    other 2023年5月7日
    00
  • 微信小程序list列表

    微信小程序list列表 微信小程序是一款高效率、易上手的小程序开发平台。在小程序中,我们常常需要展示各种信息,其中最常用的就是list列表。list列表是小程序中的一个基本组件,它可以高效地展示一系列信息,并且支持各种交互事件。 在本文中,我们将详细介绍如何使用微信小程序的list列表组件,并提供一些实用的技巧和细节。 基本使用 首先,我们需要知道如何在小程…

    其他 2023年3月28日
    00
  • 关于Js中new操作符的作用详解

    关于Js中new操作符的作用详解 在JavaScript中,new操作符用于创建一个对象实例。它的作用是通过调用构造函数来创建一个新的对象,并将该对象绑定到构造函数的原型链上。以下是关于new操作符的详细解释和示例说明: 1. 创建对象实例 new操作符用于创建一个对象实例。它会执行以下步骤:- 创建一个空对象。- 将该空对象的原型链指向构造函数的原型对象。…

    other 2023年10月15日
    00
  • Android App隐私合规检测辅助工具Camille详解

    以下是使用标准的Markdown格式文本,详细讲解Android App隐私合规检测辅助工具Camille的完整攻略: Android App隐私合规检测辅助工具Camille详解 什么是Camille? Camille是一款用于辅助Android开发者进行隐私合规检测的工具。它可以帮助开发者快速识别和解决App中可能存在的隐私问题,确保App符合相关的隐私…

    other 2023年10月14日
    00
  • linux下的常用文本编辑器

    Linux下的常用文本编辑器 在Linux系统中,与Windows和MacOS不同的是它没有自带的文本编辑器。但是,作为一个Linux用户,你有很多选项可以选择一个适合你的文本编辑器。在本文中,我们将讨论一些常用的Linux下的文本编辑器。 Vim Vim是Linux下最流行的文本编辑器之一,也是最有名的。它是以Vim编辑器的形式存在于大多数Linux系统中…

    其他 2023年3月28日
    00
  • Java 获取本机IP地址的实例代码

    获取本机IP地址是Java编程中的一个常见需求。下面是一个完整的攻略,包含了两个示例说明。 步骤1:使用InetAddress类获取本机IP地址 Java提供了InetAddress类来获取本机的IP地址。以下是获取本机IP地址的示例代码: import java.net.InetAddress; import java.net.UnknownHostExc…

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