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日

相关文章

  • Spring Bean的生命周期详细介绍

    Spring Bean的生命周期可分为以下7个阶段: 实例化Bean对象:在Spring IoC容器中,当应用程序需要使用Bean对象时,容器根据配置文件中的Bean定义信息,创建Bean对象。这个过程就是实例化Bean对象。 设置Bean属性(依赖注入):在Bean对象实例化之后,Spring IoC容器会将配置文件中Bean定义的属性值通过Setter方…

    other 2023年6月27日
    00
  • springboot+mybatis支持oracle和mysql切换含源码

    以下是详细讲解“springboot+mybatis支持oracle和mysql切换含源码的完整攻略,过程中至少包含两条示例说明”的标准Markdown格式文本: Spring Boot + MyBatis 支持 Oracle 和 MySQL 切换 本攻略将介绍如何在 Spring Boot + MyBatis 中支持 Oracle 和 MySQL 数据库的…

    other 2023年5月10日
    00
  • gitstash方法

    Git Stash方法的完整攻略 Git Stash方法是一种常用的Git命令,它可以将当前工作目录中的修改暂存起来,以便在需要时恢复。本文将提供一份关于Git Stash方法的完整攻略,包括定义、用法、示例说明以及注意事项。 定义 Git Stash方法是一种Git命令,它可以将当前工作目录中的修改暂存起来,以便在需要时恢复。Git Stash方法可以帮助…

    other 2023年5月9日
    00
  • SpringBoot优先加载指定Bean的实现

    要讲解SpringBoot优先加载指定Bean的实现,需要先理解Spring Boot中的依赖注入和Bean的加载机制。 SpringBoot中默认使用的是自动配置(auto-configuration)机制。它的实现是依赖于Spring Framework中的IoC容器和Bean的加载机制的。IoC容器是通过依赖注入(DI)来实现Bean的创建和装配的。 …

    other 2023年6月27日
    00
  • Python 启动时选择32位 或64位版的操作

    Python 启动时选择32位或64位版的操作攻略 在启动 Python 时选择使用 32 位或 64 位版本,可以根据操作系统和 Python 安装的版本进行设置。下面是详细的攻略: 步骤 1:确定操作系统和 Python 版本 首先,确定你的操作系统和已安装的 Python 版本。这将决定你可以选择的位数选项。 对于 Windows 操作系统,可以通过以…

    other 2023年7月28日
    00
  • ssh以及双机互信

    当然,我很乐意为您提供有关“ssh以及双机互信”的完整攻略。以下是详细的步骤和两个示例: 1 SSH以及双机互信 SSH一种安全的网络协议,用于在不安全的网络上安全地运行远程命令。双机互信是指两台计机之间建立互信关系,以便它们可以相互访问而无需输入密码。以下是使用SSH和双机互信的详细骤: 1.1 安装SSH 要使用SSH,您需要在计算机上安装SSH客户端和…

    other 2023年5月6日
    00
  • 公开的免费STUN服务器

    关于“公开的免费STUN服务器”的完整攻略,我可以给您提供以下内容: 什么是STUN服务器 STUN服务器 (Session Traversal Utilities for NAT) 是一个协议,用于在网络中的NAT(网络地址转换)防火墙后建立点对点的通信。NAT防火墙会对本地网络(Private network)与公共互联网(Public Internet…

    other 2023年6月27日
    00
  • java多线程创建及线程安全详解

    Java多线程创建及线程安全详解 本篇文章将详细讲解Java多线程的创建和线程安全相关内容,主要包括以下几个方面: 多线程的创建方法 线程的执行顺序与状态 线程安全的实现方法及示例 多线程的创建方法 Java多线程创建的方式主要有两种: 继承Thread类 继承Thread类是最简单的创建线程的方法,其步骤如下: 定义一个类,继承Thread类; 重写run…

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