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

yizhihongxing

创建双向链表示例

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

  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日

相关文章

  • C语言中全局数组和局部数组的问题

    下面我就来详细讲解一下“C语言中全局数组和局部数组的问题”的完整攻略。 全局数组和局部数组概念及区别 全局数组 全局数组是定义在程序的外层,函数的外面,不属于任何函数;访问全局数组时,不需要传递数组作为函数参数,就可以在程序的任何地方访问它。全局数组在定义时默认初始化为 0,或者指定初始值。全局数组的作用域为整个程序,生命周期和整个程序的生命周期一样长。 局…

    other 2023年6月25日
    00
  • vue中手动封装iconfont组件解析(三种引用方式的封装和使用)

    下面是关于“vue中手动封装iconfont组件解析(三种引用方式的封装和使用)”的详细攻略。 什么是iconfont? Iconfont是一种基于字体文件构建的图标字体技术,通常通过将多个图标文件打包成单个字体文件的方式进行管理和使用。它可以通过css嵌入到网页中,并且可以使用类似于文本属性的方式进行调用。 vue中手动封装iconfont组件 在vue中…

    other 2023年6月25日
    00
  • vue如何通过某个字段获取详细信息

    获取某个字段的详细信息,实际上是一个“筛选出符合条件的对象”的问题,因此实现这个功能需要涉及到数组的筛选和对象属性的访问。 下面是一个具体的实现步骤: 通过filter()方法筛选数组中符合条件的对象 在Vue中,可以使用filter()方法对数组进行筛选。该方法的参数是一个函数,用于对数组中的每个元素进行判断,如果返回true,则当前元素会被保留在新数组中…

    other 2023年6月25日
    00
  • 注册页面之前先验证用户名是否存在的php代码

    当用户注册时,我们经常需要对用户名进行验证,以确保用户名的唯一性。其中一种常见的做法是在注册页面之前先验证用户名是否存在。以下是一些实现此功能的php代码示例。 1. 使用mysqli进行数据库操作 首先,需要确保数据库中的用户名字段是唯一的,并且使用mysqli等扩展库连接到数据库。以下是实现此功能的代码示例: <?php // 检查是否已经提交了表…

    other 2023年6月27日
    00
  • ios学习——uialertcontroller详解

    以下是关于iOS中UIAlertController的详细攻略: 第1章:概述 UIAlertController是iOS中用于显示警告、提示和操作表的控制器。UIAlertController可以显示一个或多个按钮,以响应用户的操作。UIAlertController可以用于各种场景,如确认删除、输入密码等。 第2章:创建UIAlertController…

    other 2023年5月9日
    00
  • ubuntu系统下向U盘拷贝数据提示目标是只读的

    当在 Ubuntu 系统下向 U 盘拷贝数据时,如果提示目标是只读的,则可能是因为以下原因: U 盘的物理开关被关闭 U 盘的文件系统损坏 U 盘被当成了只读设备 解决方法如下: 确认 U 盘未被锁定 有些 U 盘会带有物理开关,当开关处于锁定状态时,系统将无法从 U 盘读取或写入数据,这可能是导致 U 盘只读的原因之一。请打开 U 盘物理开关以解锁,然后再…

    other 2023年6月27日
    00
  • 漏洞复现-CVE-2016-4437-Shiro反序列化

    漏洞复现-CVE-2016-4437-Shiro反序列化的完整攻略 简介 Apache Shiro是一个Java安全框架,提供了身份验证、授权、加密和会话管理等功能。CVE-2016-4437是Shiro框架中的一个反序列化漏洞,攻击者可以利用该漏洞在目标系统上执行任意代码。 漏洞复现 环境搭建 首先需要搭建一个漏洞环境,可以使用Shiro的一个漏洞环境搭建…

    other 2023年5月5日
    00
  • spring ioc的简单实例及bean的作用域属性解析

    Spring IOC的简单实例及Bean的作用域属性解析 什么是Spring IOC Spring IOC(Inversion of Control,控制反转)是Spring框架的核心概念之一。它通过将对象的创建和依赖关系的管理交给Spring容器来实现,从而实现了对象之间的解耦和灵活性。 Spring IOC的简单实例 下面是一个简单的Spring IOC…

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