c++双向链表操作示例(创建双向链、双向链表中查找数据、插入数据等)

创建双向链表示例

创建双向链表需要实现以下几个步骤:

  1. 定义双向链表节点结构体 Node,包含 data 数据项和 prevnext 指针分别指向前驱节点和后继节点。
  2. 定义双向链表结构体 LinkedList,包含头节点 head 和尾节点 tail,以及链表长度 size
  3. 实现 LinkedList 的构造函数,初始化头节点和尾节点,并将 headtailprevnext 指向彼此。
  4. 实现 LinkedListinsertAtTail() 方法,在链表尾部插入节点。
  5. 实现 LinkedListinsertAtHead() 方法,在链表头部插入节点。
  6. 实现 LinkedListremoveItem() 方法,删除指定节点。

以下是一个完整的 C++ 双向链表示例代码:

#include<iostream>

// 双向链表节点结构体
struct Node {
    int data;
    Node *prev;
    Node *next;
};

// 双向链表结构体
class LinkedList {
    private:
        Node *head;
        Node *tail;
        int size;

    public:
        // 构造函数
        LinkedList() {
            head = new Node();
            tail = new Node();
            head->next = tail;
            tail->prev = head;
            size = 0;
        }

        // 在链表尾部插入节点
        void insertAtTail(int value) {
            Node *node = new Node();
            node->data = value;
            node->prev = tail->prev;
            node->next = tail;
            tail->prev->next = node;
            tail->prev = node;
            size++;
        }

        // 在链表头部插入节点
        void insertAtHead(int value) {
            Node *node = new Node();
            node->data = value;
            node->prev = head;
            node->next = head->next;
            head->next->prev = node;
            head->next = node;
            size++;
        }

        // 删除指定节点
        void removeItem(Node *node) {
            node->prev->next = node->next;
            node->next->prev = node->prev;
            delete node;
            size--;
        }

        // 获取链表长度
        int getSize() {
            return size;
        }
};

int main() {
    // 创建双向链表并在尾部插入数据
    LinkedList list;
    list.insertAtTail(1);
    list.insertAtTail(2);
    list.insertAtTail(3);
    list.insertAtTail(4);

    // 遍历打印链表中的数据
    Node *currNode = list.head->next;
    while(currNode != list.tail) {
        std::cout << currNode->data << " ";
        currNode = currNode->next;
    }
    std::cout << std::endl;
    return 0;
}

双向链表中查找数据和插入数据示例

双向链表中查找数据和插入数据有多种方式,以下列举其中两种方法:

方法一:遍历查找和插入

遍历双向链表查找节点和插入节点是最基础的方法。遍历链表时从头节点开始向后遍历,直到找到目标节点或遍历到链表尾部。

以下是具体实现代码:

// 查找指定值的节点
Node *findItem(LinkedList &list, int value) {
    Node *currNode = list.head->next;
    while(currNode != list.tail) {
        if(currNode->data == value) {
            return currNode;
        }
        currNode = currNode->next;
    }
    return nullptr;
}

// 在指定值的节点后插入新节点
void insertAfter(LinkedList &list, int value, int newValue) {
    Node *currNode = list.head->next;
    while(currNode != list.tail) {
        if(currNode->data == value) {
            Node *newNode = new Node();
            newNode->data = newValue;
            newNode->prev = currNode;
            newNode->next = currNode->next;
            currNode->next->prev = newNode;
            currNode->next = newNode;
            list.size++;
            break;
        }
        currNode = currNode->next;
    }
}

方法二:使用哈希表优化查找和插入

使用哈希表优化查找和插入是一个常见的优化方法,可以在 O(1) 的时间复杂度内完成节点的查找和插入。

以下代码展示了如何使用 unordered_map(哈希表)实现快速查找和插入:

#include <unordered_map>

// 保存链表节点指针的哈希表
std::unordered_map<int, Node *> hashMap;

// 初始化哈希表
void initHashMap(LinkedList &list) {
    Node *currNode = list.head->next;
    while(currNode != list.tail) {
        hashMap[currNode->data] = currNode;
        currNode = currNode->next;
    }
}

// 查找指定值的节点
Node *findItem(LinkedList &list, int value) {
    if(hashMap.find(value) != hashMap.end()) {
        return hashMap[value];
    }
    return nullptr;
}

// 在指定值的节点后插入新节点
void insertAfter(LinkedList &list, int value, int newValue) {
    Node *currNode = findItem(list, value);
    if(currNode != nullptr) {
        Node *newNode = new Node();
        newNode->data = newValue;
        newNode->prev = currNode;
        newNode->next = currNode->next;
        currNode->next->prev = newNode;
        currNode->next = newNode;
        hashMap[newValue] = newNode;
        list.size++;
    }
}

以上两种方法根据实际场景进行选择,有时更基础的遍历法可能性能更高。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:c++双向链表操作示例(创建双向链、双向链表中查找数据、插入数据等) - Python技术站

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

相关文章

  • 详解SpringBoot程序启动时执行初始化代码

    我们来详细讲解一下如何在SpringBoot程序启动时执行初始化代码的完整攻略。 什么是SpringBoot SpringBoot是一个开箱即用的轻量级框架,它可以帮助我们快速的构建一个基于Spring的Web应用程序,简化了Spring的配置,提供了自动化配置,是一个优秀的快速开发框架。 在SpringBoot程序启动时执行初始化代码的两种方案 方案1:使…

    other 2023年6月20日
    00
  • 详解Android自定义控件属性

    想要详解Android自定义控件属性,我们需要明确三个核心的概念:自定义控件、属性和布局。自定义控件指的是继承自View或者其子类的自定义View;属性指的是我们可以通过在xml中设置的参数,来控制自定义View的展示;布局指的是如何将不同类型的View组合在一起形成一个整体。 在接下来的攻略中,我将围绕这三个核心的概念,一步一步地讲解如何创建一个具有自定义…

    other 2023年6月27日
    00
  • sasblandaltman分析

    以下是关于“SAS Bland-Altman分析”的完整攻略,包括基本概念、步骤和两个示例。 基本概念 Bland-Altman分析是一种用于比较两种测量方法的方法,它可以评估两种方法之间的一致性偏差。在SAS中,可以使用 BlandAltman命令来执行Bland-Altman分析。 步骤 以下是使用SAS执行Bland-Altman分析的步骤: 准备数据…

    other 2023年5月7日
    00
  • C语言菜鸟基础教程之常量和变量

    下面我会为你详细讲解“C语言菜鸟基础教程之常量和变量”的完整攻略。 常量和变量 常量 什么是常量 在C语言中,常量就是一个固定的值,在程序中不会改变。 常量可分为以下几种: 整型常量,如2、10、-10。 实数常量,如3.14、0.01。 字符常量,如’a’、’B’、’#’。 字符串常量,如”hello world”。 枚举常量,如enum性别{男,女},男…

    other 2023年6月27日
    00
  • Java 1.0和Java 1.1 的IO类的比较

    Java 1.0和Java 1.1 的IO类是Java中最基本的操作之一,它包括输入和输出两个部分,其中输入InputStream和输出OutputStream是Java 1.0和Java 1.1的IO类最基础的部分。下面我们来一起详细讲解一下Java 1.0和Java 1.1 的IO类的比较。 Java 1.0的IO类 Java 1.0的IO类使用较为简单…

    other 2023年6月26日
    00
  • vue中如何获取session对象中的属性值

    Vue.js 中如何获取 Session 对象中的属性值 当我们开发前端 Web 应用的时候,常常需要与后端交互获取数据。在这些数据中,可能需要从 Session 对象中获取我们需要的字段值。那么在 Vue.js 中,我们该如何获取 Session 对象中的属性值呢?本文将会提供几种方法来实现这个目标。 通过 HTTP Cookie 获取 SessionID…

    其他 2023年3月29日
    00
  • node.js+postman实现模拟HTTP服务器与客户端交互

    Node.js 是一种基于 Chrome V8 引擎的 JavaScript 运行时,使 JavaScript 可以在服务端运行,同时提供了丰富的模块库,可以用于快速搭建 Web 应用、命令行工具等。 Postman 是一个 API 测试工具,提供了丰富的功能,可以模拟客户端发起 HTTP 请求,方便开发人员进行接口测试和调试。 下面是使用 Node.js …

    other 2023年6月27日
    00
  • win10更新右键没有卸载怎么解决?

    Win10更新右键没有卸载怎么解决? 如果在Win10更新后,发现右键没有卸载选项,可以尝试以下方法解决: 方法一 按Win + R键打开运行窗口,输入regedit,打开注册表编辑器。 在注册表编辑器中,找到以下路径: HKEY_CLASSES_ROOT\*\shellex\ContextMenuHandlers 找到名为“Comodo Antivirus…

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