数组,链表,红黑树介绍以及性能对比实验

news2024/11/23 19:10:32

作者:晓宜
🌈🌈🌈
个人简介:携程javaer,阿里云专家博主,csdn后端优质创作者,算法爱好者
❤️❤️❤️
一起进步!!!😊

前言

以前学了数组,链表,红黑树的相关知识,今天用Java对它们三者在插入,删除,查找等方面做一个性能对比测试,今天分享给大家😊

数据结构

1. ArrayList

ArrayList底层是基于动态数组实现的。其特点包括:

数据结构:动态数组。
访问时间:通过索引访问元素的时间复杂度为O(1),因为可以直接通过索引定位到元素。
插入和删除:在尾部插入元素的时间复杂度为O(1)。在中间插入或删除元素的时间复杂度为O(n),因为需要移动元素来保持数组的连续性。
扩容机制:当数组容量不够时,ArrayList会创建一个更大的数组(通常是原容量的1.5倍左右),然后将旧数组中的元素复制到新数组中。

2.LinkedList

LinkedList底层是基于双向链表实现的。其特点包括:

数据结构:双向链表,每个节点包含一个数据元素以及指向前后节点的引用。
访问时间:访问元素的时间复杂度为O(n),因为需要从头节点或尾节点遍历链表找到目标节点。
插入和删除:在链表头部或尾部插入和删除元素的时间复杂度为O(1)。在链表中间插入和删除元素的时间复杂度为O(n),因为需要先遍历找到插入或删除位置。
灵活性:适用于频繁插入和删除操作的场景,但随机访问效率较低。

3. TreeMap

TreeMap底层是基于红黑树(Red-Black Tree)实现的。其特点包括:

数据结构:红黑树,一种自平衡的二叉搜索树。
访问时间:查找、插入和删除操作的时间复杂度为O(log n),因为红黑树在最坏情况下的高度为O(log n)。
键排序:TreeMap中的元素按照键的自然顺序或指定的比较器排序。
有序性:提供按键值排序的特性,可以方便地进行范围查询和有序遍历。

实验代码

我们先讲一下代码具体做了些什么,在代码中,我创造了三个函数,分别对应三个数据结构:数组,链表,红黑树。在每个函数中,我会先创建这样一个数据结构对象和一个随机数对象,接下来执行三步:

  1. 用随机数对象生成1000个随机数,先插入到刚才生成的数据结构中,计算时间
  2. 生成1000个随机数,在数据结构中查找是否存在这个数,计算时间
  3. 生成1000个随机数,随机生成一个索引,删除这个索引对应的数,计算时间

这里是其中一次测试的结果:
在这里插入图片描述
在这次测试中,我们发现红黑树的查找和删除性能是最优秀的,但是其插入的效率是最低的,这是因为他在插入过程中需要构建红黑树的结构;链表的插入,查询和删除效率都是最低的;数组插入,删除,查询的效率居中。感兴趣的小伙伴可以自己做这样一个实验😎,代码如下:

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Random;
import java.util.TreeMap;

public class PerformanceTest {

    public static void RedBlack(ArrayList<Integer> testList) {
        // 创建 TreeMap
        TreeMap<Integer, Integer> treeMap = new TreeMap<>();
        Random random = new Random();
        int dataSize = testList.size(); // 数据规模

        // 生成随机数据并插入
        long startTime = System.nanoTime();
        for (int i = 0; i < dataSize; i++) {
            int key = random.nextInt(dataSize); // 随机生成键
            int value = testList.get(i); // 随机生成值
            treeMap.put(key, value);
        }
        long insertTime = System.nanoTime() - startTime;

        // 随机查找
        startTime = System.nanoTime();
        for (int i = 0; i < 1000; i++) {
            int key = random.nextInt(dataSize); // 随机生成键
            treeMap.containsKey(key);
        }
        long searchTime = System.nanoTime() - startTime;

        // 随机删除
        startTime = System.nanoTime();
        for (int i = 0; i < 1000; i++) {
            int key = random.nextInt(dataSize); // 随机生成键
            treeMap.remove(key);
        }
        long deleteTime = System.nanoTime() - startTime;

        // 打印时间
        System.out.println("Insertion time: " + insertTime / 1000000.0 + " ms");
        System.out.println("Search time: " + searchTime / 1000000.0 + " ms");
        System.out.println("Deletion time: " + deleteTime / 1000000.0 + " ms");
    }

    public static void Linkedlist(ArrayList<Integer> testList) {
        // 数据规模
        int dataSize = testList.size();
        // 创建链表
        LinkedList<Integer> linkedList = new LinkedList<>();
        // 随机数生成器
        Random random = new Random();

        // 生成随机数据并插入
        long startTime = System.nanoTime();
        for (int i = 0; i < dataSize; i++) {
            linkedList.add(testList.get(i)); // 随机生成数据并插入链表
        }
        long insertTime = System.nanoTime() - startTime;

        // 随机查找1000次,计算查找时间
        startTime = System.nanoTime();
        for (int i = 0; i < 1000; i++) {
            int randomData = random.nextInt(); // 随机生成数据
            boolean found = linkedList.contains(randomData); // 查找数据
        }
        long searchTime = System.nanoTime() - startTime;

        // 随机删除1000次,计算删除时间
        startTime = System.nanoTime();
        for (int i = 0; i < 1000; i++) {
            int randomIndex = random.nextInt(linkedList.size()); // 随机生成索引
            linkedList.remove(randomIndex); // 删除元素
        }
        long deleteTime = System.nanoTime() - startTime;

        // 打印时间
        System.out.println("Insertion time: " + insertTime / 1000000.0 + " ms");
        System.out.println("Search time: " + searchTime / 1000000.0 + " ms");
        System.out.println("Deletion time: " + deleteTime / 1000000.0 + " ms");
    }

    public static void ArrayList(ArrayList<Integer> testList) {
        // 数据规模
        int dataSize = testList.size();
        // 创建ArrayList
        ArrayList<Integer> arrayList = new ArrayList<>();
        // 随机数生成器
        Random random = new Random();

        // 生成随机数据并插入
        long startTime = System.nanoTime();
        for (int i = 0; i < dataSize; i++) {
            arrayList.add(testList.get(i)); // 随机生成数据并插入ArrayList
        }
        long insertTime = System.nanoTime() - startTime;

        // 随机查找1000次,计算查找时间
        startTime = System.nanoTime();
        for (int i = 0; i < 1000; i++) {
            int randomValue = random.nextInt(); // 随机生成值
            boolean found = arrayList.contains(randomValue); // 查找值是否存在
        }
        long searchTime = System.nanoTime() - startTime;

        // 随机删除1000次,计算删除时间
        startTime = System.nanoTime();
        for (int i = 0; i < 1000; i++) {
            int randomIndex = random.nextInt(arrayList.size()); // 随机生成索引
            arrayList.remove(randomIndex); // 删除元素
        }
        long deleteTime = System.nanoTime() - startTime;

        // 打印时间
        System.out.println("Insertion time: " + insertTime / 1000000.0 + " ms");
        System.out.println("Search time: " + searchTime / 1000000.0 + " ms");
        System.out.println("Deletion time: " + deleteTime / 1000000.0 + " ms");
    }

    public static void main(String[] args) {
        // 数据规模
        int dataSize = 1_000_000;
        // 创建ArrayList
        ArrayList<Integer> testList = new ArrayList<>();
        // 随机数生成器
        Random random = new Random();

        for (int i = 0; i < dataSize; i++) {
            testList.add(random.nextInt()); // 随机生成数据并插入
        }

        ArrayList(testList);
        System.out.println("ArrayList done\n");

        Linkedlist(testList);
        System.out.println("LinkedList done\n");

        RedBlack(testList);
        System.out.println("RedBlack done\n");

    }
}

项目链接:

代码链接

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1862507.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

安装zabbix时报错Could not resolve host: mirrors.huaweicloud.com;Unknown error解决办法

目录 1、问题原因 2、解决办法 3、知识拓展 DNS的区别 DNS配置文件解析 域名解析过程 4、书籍推荐 当安装Zabbix server&#xff0c;Web前端&#xff0c;agent时出现&#xff1a; [rootsc-zabbix-server ~]# yum install zabbix-server-mysql zabbix-agent安装过程中会出…

【咨询】企业数字档案馆建设规划建议书-模版范例

导读&#xff1a;本文提供范例可以作为xxx建设规划建议书模版 建议书结构 第一章 项目背景及意义 1.1.企业数字档案馆建设是构建新质生产力的重要抓手 1.2.企业数字档案馆建设是落实全国档案事业发展规划的重要支撑 1.3.企业数字档案馆建设是支撑提质增效、高质量发展的有效…

利用scalene进行性能分析和优化

​ 上一篇文章&#xff0c;我们详细讲解了Py-Spy这个性能分析和优化工具的使用流程&#xff1b;今天&#xff0c;我们将深入探讨另一个性能分析和优化工具——scalene。 什么是scalene&#xff1f; scalene是一个高精度的Python性能分析工具&#xff0c;可以对CPU和内存使用情…

为什么说大数据对电子商务卖家至关重要?||电商API接口

从数据中获取价值的重要性&#xff0c;远甚以往。 由于新冠的爆发&#xff0c;所有B2B公司都被迫将业务转到线上的电子商务平台以加速数字化转型&#xff1b;而随着疫情逐渐褪去&#xff0c;这种线上线下混合的趋势得以进一步加强。 企业希望能够在自己选定的设备上&#xff0c…

视频太大如何压缩上传微信

视频太大如何压缩上传微信&#xff0c;视频已成为人们生活中不可或缺的一部分。然而&#xff0c;视频文件的大小也在不断增加&#xff0c;这给存储和传输带来了极大的挑战。下面给大家分享一个视频太大不能发微信的解决方法。 打开 “51视频处理官网 的网站。上传视频。 ​视频…

CentOS9镜像下载地址加速下载

CentOS 9 是 CentOS 项目的最新版本之一&#xff0c;它基于 RHEL&#xff08;Red Hat Enterprise Linux&#xff09;9 的源代码构建。CentOS&#xff08;Community ENTerprise Operating System&#xff09;是一个免费的企业级 Linux 发行版&#xff0c;旨在提供一个与 RHEL 兼…

花样玩转“所见即所得”的可视化开发UI

随着技术的发展&#xff0c;用户对软件的界面美观度和交互体验的要求越来越高。在这样的背景下&#xff0c;可视化开发UI&#xff08;User Interface&#xff09;成为了提升用户体验和开发效率的重要工具。 通过图形界面来设计和构建用户界面的方法&#xff0c;可视化开发UI可…

ROS CDK魔法书:点亮博客上云新技能(TypeScript篇)

引言 在数字世界的浩瀚海洋中&#xff0c;信息与数据如同戏剧中的主角&#xff0c;舞动着无形的旋律&#xff0c;构建起信息时代的交响乐。而在这其中&#xff0c;作为一位技术领域的探索者&#xff0c;你的使命便是挥舞着编码的魔杖&#xff0c;创造和守护着这些宝贵的数字灵…

吉时利 Keithley2440 数字源表

Keithley2440吉时利SMU数字源表 Keithley2440 - 40V、5A、50W源表 吉时利数字源表系列专用于要求紧密结合源和测量 的测试应用。全部数字源表型号都提供精密电压源和电 流源以及测量功能。每款数字源表既是高度稳定的直流 电源也是真仪器级的6位半万用表。此电源的特性包括 低…

Android副屏多屏异显原来如此简单

省流介绍 安卓副屏开发&#xff0c;直接继承dialog&#xff0c;会写dialog&#xff0c;直接指定屏幕显示完事&#xff0c;模拟器和手机开发者里面支持单屏幕调试 详细看文章尾部 public class Presentation extends Dialog class Screen2 : Presentation {constructor(outer…

go语言day06 数组 切片

数组 : 定长且元素类型一致,在索引逻辑上连续存储,数组的内存地址是存储的第一个元素的内存地址 几种创建方式: 仅声明 var nums [ 3 ] int 声明并赋值 var nums [ 2 ] string {"武沛齐","alex"} 声明并按下标赋值 var nums [ 3 ] int {0:88,2:1 } 省略…

机器人控制系列教程之运动规划(2)

简介 在笛卡尔坐标空间中轨迹规划时&#xff0c;首先用位置矢量和旋转矩阵表示所有相应的机器人节点&#xff0c;其次在所有路径段插值计算相对的位置矢量和旋转矩阵&#xff0c;依次得出笛卡尔坐标空间中的轨迹序列通过求解运动学逆问题得到相应关节位置参数。 优点&#xf…

绘制图形

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 在前3节的实例中&#xff0c;我们一直绘制的都是直线&#xff0c;实际上&#xff0c;海龟绘图还可以绘制其他形状的图形&#xff0c;如圆形、多边形等…

通过frp实现内外网映射

frp介绍和使用方法可以参考官网:安装 | frp 1、准备两台服务器&#xff0c;一台内网服务器A&#xff0c;一台有公网ip的外网服务器B(47.12.13.15) 2、去官方仓库下载frp安装包&#xff1a;Releases fatedier/frp GitHub 下载包根据自己服务系统选择 ​ 3、先在外网服务器…

类的默认成员函数——拷贝构造函数

1.概念引入 在现实生活中&#xff0c;如果有两个兄弟长得一模一样&#xff0c;我们就称其为双胞胎 当我们创建了一个新的对象&#xff0c;需要用同类型的对象拷贝并初始化&#xff0c;就要用到拷贝构造函数 拷贝构造函数&#xff1a;只有单个形参&#xff0c;该形参是对本类类…

2024 年 8 款最佳建筑 3D 渲染软件

你现在使用的3D 渲染软件真得适合你吗&#xff1f; 在建筑和室内渲染当中&#xff0c;市面上有许多3D渲染软件可供选择。然而&#xff0c;并不是每款软件都适合你的需求。本指南将重点介绍2024年精选的8款最佳建筑3D渲染软件&#xff0c;帮助你了解不同的选项&#xff0c;并选…

STM32的SPI通信

1 SPI协议简介 SPI&#xff08;Serial Peripheral Interface&#xff09;协议是由摩托罗拉公司提出的通信协议&#xff0c;即串行外围设备接口&#xff0c;是一种高速全双工的通信总线。它被广泛地使用在ADC、LCD等设备与MCU间&#xff0c;使用于对通信速率要求较高的场合。 …

基于Java的宠物领养管理系统【附源码】

摘 要 近些年来&#xff0c;随着科技的飞速发展&#xff0c;互联网的普及逐渐延伸到各行各业中&#xff0c;给人们生活带来了十分的便利&#xff0c;宠物管理系统利用计算机网络实现信息化管理&#xff0c;使整个宠物领养的发展和服务水平有显著提升。 本文拟采用IDEA开发工具…

Live Wallpaper Themes 4K Pro for Mac v19.9 超高清4K动态壁纸

Live Wallpaper & Themes 4K Pro for Mac v19.7 是一款专为Mac用户设计的超高清4K动态壁纸应用程序。它凭借出色的视觉效果和丰富的个性化设置&#xff0c;为用户带来全新的桌面体验。 这款软件提供了大量精美的动态壁纸供用户选择&#xff0c;涵盖了各种风格和主题&#…

考个嵌入式中级证书吧,有大用!

随着物联网、人工智能的蓬勃发展&#xff0c;嵌入式行业迎来了前所未有的发展机遇&#xff1a;物联网的万物互联需求&#xff0c;为嵌入式系统开拓了广阔的应用场景&#xff1b;人工智能的融入促使嵌入式设备向更智能、更自主的方向进化。然而&#xff0c;行业的火爆&#xff0…