C++模拟实现JDK中的ArrayList和LinkedList

C++模拟实现JDK中的ArrayList和LinkedList

介绍

在Java语言中,ArrayList和LinkedList是两种常见的List集合实现方式。ArrayList底层基于动态数组实现,适用于随机访问元素,但插入和删除操作效率较低。LinkedList底层基于双向链表实现,适用于频繁插入和删除操作,但访问元素效率较低。

本篇文章将介绍如何使用C++语言模拟实现ArrayList和LinkedList,实现它们基本的操作。

C++实现ArrayList

数据结构

在C++中,可以使用std::vector代替Java中的ArrayList,std::vector基于动态数组实现,使用前需要包含< vector >头文件。

#include <vector>
#include <iostream>

using namespace std;

int main() {
    vector<int> arrlist;
    arrlist.push_back(1);
    arrlist.push_back(2);
    arrlist.push_back(3);
    for(int i=0; i<arrlist.size(); i++) {
        cout << arrlist[i] << " ";
    }
    cout << endl;
    return 0;
}

运行结果为:1 2 3

基本操作

在C++中,可以使用std::vector实现ArrayList的基本操作,包括插入、删除、获取元素、获取大小等。

vector<int> arrlist;
arrlist.push_back(1); // 插入元素1
arrlist.push_back(2); // 插入元素2
arrlist.push_back(3); // 插入元素3

arrlist.erase(arrlist.begin() + 1); // 删除第二个元素2
cout << arrlist[1] << endl; // 输出第二个元素3

string s = "size: " + to_string(arrlist.size()); // 获取元素个数
cout << s << endl; // 输出size: 2

C++实现LinkedList

数据结构

在C++中,可以使用自定义结构体实现链表,包括链表节点和链表类。

#include <iostream>

/* 链表节点 */
struct Node {
    int val; // 节点值
    Node* prev; // 前驱指针
    Node* next; // 后继指针
    Node(int val) : val(val), prev(nullptr), next(nullptr) {} // 构造函数
};

/* 链表类 */
class LinkedList {
public:
    LinkedList() : head(nullptr), tail(nullptr) {} // 构造函数

    void addFirst(int val); // 在头部添加节点
    void addLast(int val); // 在尾部添加节点
    void insert(int val, int index); // 在指定位置插入节点
    void removeFirst(); // 删除头部节点
    void removeLast(); // 删除尾部节点
    void remove(int index); // 删除指定位置的节点
    int get(int index); // 获取指定位置的节点值
    int size(); // 获取节点总数

private:
    Node* head; // 头节点指针
    Node* tail; // 尾节点指针
};

int main() {
    LinkedList linkedlist;
    linkedlist.addFirst(1);
    linkedlist.addLast(3);
    linkedlist.insert(2, 1);
    linkedlist.remove(1);
    std::cout << linkedlist.get(1) << std::endl;
    std::cout << linkedlist.size() << std::endl;
    return 0;
}

基本操作

在C++中,根据链表节点的前驱指针和后继指针,可以实现链表的基本操作,包括在头部、尾部和指定位置插入节点,删除头部、尾部和指定位置的节点,获取指定位置的节点值和获取总节点数。

void LinkedList::addFirst(int val) {
    Node* node = new Node(val);
    if(head == nullptr) {
        head = node;
        tail = node;
    } else {
        node->next = head;
        head->prev = node;
        head = node;
    }
}

void LinkedList::addLast(int val) {
    Node* node = new Node(val);
    if(tail == nullptr) {
        head = node;
        tail = node;
    } else {
        node->prev = tail;
        tail->next = node;
        tail = node;
    }
}

void LinkedList::insert(int val, int index) {
    Node* node = new Node(val);
    Node* p = head;
    for(int i=0; i<index-1 && p!=nullptr; i++) {
        p = p->next;
    }
    if(p == nullptr) { // 插入位置越界
        std::cout << "Out of range!" << std::endl;
        return;
    }
    if(p == head) {
        addFirst(val);
        return;
    }
    node->prev = p->prev;
    node->next = p;
    p->prev->next = node;
    p->prev = node;
}

void LinkedList::removeFirst() {
    if(head == nullptr) {
        return;
    }
    Node* p = head;
    head = head->next;
    if(head != nullptr) {
        head->prev = nullptr;
    } else {
        tail = nullptr;
    }
    delete p;
}

void LinkedList::removeLast() {
    if(tail == nullptr) {
        return;
    }
    Node* p = tail;
    tail = tail->prev;
    if(tail != nullptr) {
        tail->next = nullptr;
    } else {
        head = nullptr;
    }
    delete p;
}

void LinkedList::remove(int index) {
    Node* p = head;
    for(int i=0; i<index && p!=nullptr; i++) {
        p = p->next;
    }
    if(p == nullptr) { // 删除位置越界
        std::cout << "Out of range!" << std::endl;
        return;
    }
    if(p == head) {
        removeFirst();
        return;
    }
    if(p == tail) {
        removeLast();
        return;
    }
    p->prev->next = p->next;
    p->next->prev = p->prev;
    delete p;
}

int LinkedList::get(int index) {
    Node* p = head;
    for(int i=0; i<index && p!=nullptr; i++) {
        p = p->next;
    }
    if(p == nullptr) { // 获取位置越界
        std::cout << "Out of range!" << std::endl;
        return -1;
    }
    return p->val;
}

int LinkedList::size() {
    Node* p = head;
    int count = 0;
    while(p != nullptr) {
        count++;
        p = p->next;
    }
    return count;
}

总结

本篇文章介绍了如何使用C++语言模拟实现ArrayList和LinkedList,基于std::vector实现了ArrayList的基本操作,基于自定义结构体实现了LinkedList的基本操作,包括插入、删除、获取元素和获取大小。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++模拟实现JDK中的ArrayList和LinkedList - Python技术站

(0)
上一篇 2023年3月28日
下一篇 2023年3月28日

相关文章

  • Spring创建IOC容器的方式解析

    Spring创建IOC容器的方式解析 Spring是一个强大的Java开发框架,它提供了多种方式来创建IOC(控制反转)容器,用于管理和组织应用程序中的对象。以下是Spring创建IOC容器的几种常见方式: 1. XML配置文件方式 使用XML配置文件是最传统和常见的创建IOC容器的方式。在XML配置文件中,我们可以定义Bean的名称、类型、依赖关系等信息。…

    other 2023年10月17日
    00
  • 最强蜗牛巨龙形态解锁、基因研究加成与形态仪式 巨龙形态攻略大全

    最强蜗牛巨龙形态解锁攻略 蜗牛巨龙是非常强大的神兽,而它的最强形态需要解锁才能使用。以下是解锁最强蜗牛巨龙形态的攻略: 收集4块雪山龙与2条快龙的基因 雪山龙和快龙是最强蜗牛巨龙形态的基因来源。可以通过打败野生的雪山龙和快龙,或者通过神兽交换中心交换得到。收集完这些基因后,可以前往形态仪式地点进化形态。 进化蜗牛巨龙到第二阶段 在解锁最强蜗牛巨龙形态之前,需…

    other 2023年6月27日
    00
  • 浅谈tudou土豆网首页图片延迟加载的效果

    下面是关于“浅谈tudou土豆网首页图片延迟加载的效果”的完整攻略: 一、什么是图片延迟加载? 图片延迟加载(也称为“懒加载”)是一种优化网站加载速度的技术,它可以使图片在用户滚动到它们所在的位置时再进行加载,而不是一次性加载所有图片。这样可以减少页面的加载时间和带宽使用,提高用户体验。 二、tudou土豆网首页图片延迟加载的实现方法 tudou土豆网的首页…

    other 2023年6月25日
    00
  • Windows Server 2012 R2或2016无法安装.NET Framework 3.5.1的解决方法

    下面是详细的攻略步骤: 1. 确认Windows Server版本 首先,需要确认所使用的Windows Server版本是2012 R2或2016版,因为只有这两个版本才会出现无法安装.NET Framework 3.5.1的问题。 2. 启用.NET Framework 3.5.1框架 在Windows Server 2012 R2或2016中,默认情况…

    other 2023年6月27日
    00
  • 解决Navicat Premium 12连接Oracle时提示oracle library is not loaded的问题

    下面是详细讲解“解决Navicat Premium 12连接Oracle时提示oracle library is not loaded的问题”的完整攻略。 问题背景 在使用 Navicat Premium 12 连接 Oracle 数据库时,会遇到以下错误提示: oracle library is not loaded 这是因为 Navicat 在连接 Or…

    other 2023年6月27日
    00
  • Linux终端命令行的常用快捷键详解

    标题:Linux终端命令行的常用快捷键详解 正文: 快捷键是Linux终端命令行的一项非常重要的功能,能够提高命令行操作的效率。下面将对常用的Linux终端命令行快捷键进行详细讲解。 常用快捷键 控制命令输入 Ctrl + a:将光标移动到命令行的开头。 Ctrl + e:将光标移动到命令行的末尾。 Ctrl + u:删除从光标位置到行首的所有内容。 Ctr…

    other 2023年6月26日
    00
  • 微信开发者工具怎么设置上拉触底?微信开发者工具设置上拉触底教程

    当我们在微信开发者工具中开发小程序时,经常需要实现上拉加载更多的功能,这可以通过设置“上拉触底”的方式来实现。 下面是具体的操作步骤: 步骤一:在app.json中配置 在app.json文件中,我们可以通过设置window对象中的enablePullDownRefresh属性为true来启用下拉刷新功能。而要开启上拉加载更多功能,我们需要设置这个属性的另一…

    other 2023年6月26日
    00
  • Spring框架构造注入操作实战案例

    Spring框架构造注入操作实战案例攻略 简介 Spring框架是一个开源的Java应用程序框架,它提供了一种轻量级的解决方案来构建企业级应用程序。其中,构造注入是Spring框架中的一种依赖注入方式,通过构造函数来注入依赖对象。本攻略将详细介绍如何在Spring框架中使用构造注入,并提供两个示例说明。 步骤 步骤一:配置Spring环境 首先,确保你已经正…

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