16 张图带你搞懂 Java 数据结构,从此想不飘都难!_java数据结构-程序员宅基地

技术标签: 算法  java  二叉树  链表  Java进阶之路  数据结构  

CSDN 的小伙伴们,大家好,我是沉默的王二。

假期结束了,需要快速切换到工作的状态投入到新的一天当中。放假的时候痛快地玩耍,上班的时候积极的工作,这应该是我们大多数“现代人”该有的生活状态。

今天我们来学一下数据结构方面的知识,对扎实 Java 的基本功非常有用,学会了就会有一种自带大佬的感觉,嘿嘿。数据结构,也就是 Data Structure,是一种存储数据的结构体,数据与数据之间存在着一定的关系,这样的关系有数据的逻辑关系、数据的存储关系和数据的运算关系。

在 Java 中,数据结构一般可以分为两大类:线性数据结构和非线性数据结构。哈哈,这个非字很有灵魂吧?

先来说线性数据结构吧。

1)数组

一眼看上去就知道的,像 String []int [] 这种;还有需要看两眼才能看透的(看源码了),像 ArrayList,内部对数组进行了封装。

数组这种数据结构最大的好处,就是可以根据下标(或者叫索引)进行操作,插入的时候可以根据下标直接插入到具体的位置,但与此同时,后面的元素就需要全部向后移动,需要移动的数据越多,就越累。

假设现在已经有了一个 ArrayList 了,准备在第 4 个位置(下标为 3)上添加一个元素 55。

此时 ArrayList 中第 5 个位置以后的元素将会向后移动。

准备把 23 从 ArrayList 中移除。

此时下标为 7、8、9 的元素往前挪。

简单总结一下 ArrayList 的时间复杂度,方便大家在学习的时候作为参考。

1、通过下标(也就是 get(int index))访问一个元素的时间复杂度为 O(1),因为是直达的,无论数据增大多少倍,耗时都不变。

2、添加一个元素(也就是 add())的时间复杂度为 O(1),因为直接添加到末尾。

3、删除一个元素的时间复杂度为 O(n),因为要遍历列表,数据量增大几倍,耗时也增大几倍。

4、查找一个未排序的列表时间复杂度为 O(n),因为要遍历列表;查找排序过的列表时间复杂度为 O(log n),因为可以使用二分查找法,当数据增大 n 倍时,耗时增大 logn 倍(这里的 log 是以 2 为底的,每找一次排除一半的可能)。

2)链表

链表在物理存储空间是不连续的,但每个节点要么知道它的下一个节点是谁,要么知道它的上一个节点是谁,仿佛就像我们之间隔着千山万水,却心有灵犀一点链。像 LinkedList 就是最典型的链表结构,通过引用相互链接。

LinkedList 中的每一个元素都可以称之为节点(Node),每一个节点都包含三个项目:其一是元素本身,其二是指向下一个元素的引用地址,其三是指向上一个元素的引用地址。

LinkedList 看起来就像下面这个样子:

  • 第一个节点由于没有前一个节点,所以 prev 为 null;
  • 最后一个节点由于没有后一个节点,所以 next 为 null;
  • 这是一个双向链表,每一个节点都由三部分组成,前后节点和值。

相比 ArrayList,LinkedList 有以下优势:

1、LinkedList 允许内存进行动态分配,这就意味着内存分配是由编译器在运行时完成的,我们无需在 LinkedList 声明的时候指定大小。

2、LinkedList 不需要在连续的位置上存储元素,因为节点可以通过引用指定下一个节点或者前一个节点。也就是说,LinkedList 在插入和删除元素的时候代价很低,因为不需要移动其他元素,只需要更新前一个节点和后一个节点的引用地址即可。

3)栈

栈是一种非常有用的数据结构,它就像一摞盘子,第一个放在最下面,第二个放在第一个上面,第三个放在第二个上面,最后一个放在最上面。栈遵循后进先出的原则,也就是“Last In First Out”(简称 LIFO)——最后的一个进的,最先出去。

对于栈这样一个数据结构来说,它有两个常见的动作:

  • push,中文释义有很多种,我个人更喜欢叫它“压入”,非常形象。当我们要把一个数据放入栈的顶部,这个动作就叫做 push

  • pop,同样的,我个人更喜欢叫它“弹出”,带有很强烈的动画效果,有没有?当我们要从栈中移除一个数据时,这个动作就叫做 pop

4)队列

队列,只允许在队尾添加数据,队首移除数据。队列在 Java 中的出现频率非常高,有各种不同的类来满足不同的场景需求。像优先级队列 PriorityQueue、延时队列 DelayQueue 等等。队列遵循的是 First In First Out,缩写为 FIFO,也就是先进先出,第一个进入队列的第一个先出来。

再来说非线性数据结构。

1) 树

树是一种典型的非线性结构,它是由 n(n>0)个有限节点组成的一个具有层次关系的集合。之所以叫“树”,是因为这种数据结构看起来就像是一个倒挂的树,只不过根在上,叶在下。树形数据结构有以下这些特点:

  • 每个节点都只有有限个子节点或无子节点;
  • 没有父节点的节点称为根节点;
  • 每一个非根节点有且只有一个父节点;
  • 除了根节点外,每个子节点可以分为多个不相交的子树。

下图展示了树的一些术语:

根节点是第 0 层,它的子节点是第 1 层,子节点的子节点为第 2 层,以此类推。

  • 深度:对于任意节点 n,n 的深度为从根到 n 的唯一路径长,根的深度为 0。
  • 高度:对于任意节点 n,n 的高度为从 n 到一片树叶的最长路径长,所有树叶的高度为 0。

树又可以细分为下面几种:

1、普通树:对子节点没有任何约束。

2、二叉树:每个节点最多含有两个子节点的树。 二叉树按照不同的表现形式又可以分为多种。

2.1、普通二叉树:每个子节点的父节点不一定有两个子节点的二叉树。

2.2、完全二叉树:对于一颗二叉树,假设其深度为d(d>1)。除了第 d 层外,其它各层的节点数目均已达最大值,且第 d 层所有节点从左向右连续地紧密排列。

2.3、满二叉树:一颗每一层的节点数都达到了最大值的二叉树。有两种表现形式,第一种,像下图这样(每一层都是满的),满足每一层的节点数都达到了最大值 2。

3、二叉查找树:英文名叫 Binary Search Tree,即 BST,需要满足以下条件:

  • 任意节点的左子树不空,左子树上所有节点的值均小于它的根节点的值;
  • 任意节点的右子树不空,右子树上所有节点的值均大于它的根节点的值;
  • 任意节点的左、右子树也分别为二叉查找树。

3.1、平衡二叉树:当且仅当任何节点的两棵子树的高度差不大于 1 的二叉树。由前苏联的数学家 Adelse-Velskil 和 Landis 在 1962 年提出的高度平衡的二叉树,根据科学家的英文名也称为 AVL 树。

平衡二叉树本质上也是一颗二叉查找树,不过为了限制左右子树的高度差,避免出现倾斜树等偏向于线性结构演化的情况,所以对二叉搜索树中每个节点的左右子树作了限制,左右子树的高度差称之为平衡因子,树中每个节点的平衡因子绝对值不大于 1。

平衡二叉树的难点在于,当删除或者增加节点的情况下,如何通过左旋或者右旋的方式来保持左右平衡。

红黑树是一种常见的平衡二叉树,节点是红色或者黑色,通过颜色的约束来维持着二叉树的平衡:

  • 每个节点都只能是红色或者黑色
  • 根节点是黑色
  • 每个叶节点(NIL 节点,空节点)是黑色的。
  • 如果一个节点是红色的,则它两个子节点都是黑色的。也就是说在一条路径上不能出现相邻的两个红色节点。
  • 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。

4、B 树:一种对读写操作进行优化的自平衡的二叉查找树,能够保持数据有序,拥有多于两个的子树。

5、B+ 树:B 树的变体。

HashMap 里面的 TreeNode 就用到了红黑树,而 B 树、B+ 树在数据库的索引原理里面有典型的应用。

2)哈希表

哈希表(Hash Table),也叫散列表,是一种可以通过关键码值(key-value)直接访问的数据结构,它最大的特点就是可以快速实现查找、插入和删除。其中用到的算法叫做哈希,就是把任意长度的输入,变换成固定长度的输出,该输出就是哈希值。像 MD5、SHA1 都用的是哈希算法。

每一个 Java 对象都会有一个哈希值,默认情况就是通过调用本地方法执行哈希算法,计算出对象的内存地址 + 对象的值的关键码值。

数组的最大特点就是查找容易,插入和删除困难;而链表正好相反,查找困难,而插入和删除容易。哈希表很完美地结合了两者的优点, Java 的 HashMap 在此基础上还加入了树的优点。

哈希表具有较快(常量级)的查询速度,以及相对较快的增删速度,所以很适合在海量数据的环境中使用。

对于任意两个不同的数据块,其哈希值相同的可能性极小,也就是说,对于一个给定的数据块,找到和它哈希值相同的数据块极为困难。再者,对于一个数据块,哪怕只改动它的一个比特位,其哈希值的改动也会非常的大——这正是 Hash 存在的价值!

尽管可能性极小,但仍然会发生,如果哈希冲突了,Java 的 HashMap 会在数组的同一个位置上增加链表,如果链表的长度大于 8,将会转化成红黑树进行处理——这就是所谓的拉链法(数组+链表)。

3)图

图是一种复杂的非线性结构,由顶点的有穷非空集合和顶点之间边的集合组成,通常表示为:G(V,E),其中,G 表示一个图,V 是图 G 中顶点的集合,E 是图 G 中边的集合。

上图共有 V0,V1,V2,V3 这 4 个顶点,4 个顶点之间共有 5 条边。

在线性结构中,数据元素之间满足唯一的线性关系,每个数据元素(除第一个和最后一个外)均有唯一的“前驱”和“后继”;

在树形结构中,数据元素之间有着明显的层次关系,并且每个数据元素只与上一层中的一个元素(父节点)及下一层的多个元素(子节点)相关;

而在图形结构中,节点之间的关系是任意的,图中任意两个数据元素之间都有可能相关。

最后,希望大家都能把 Java 数据结构学好,从一键三连做起吧

推荐阅读:

V4.0 《JavaGuide 面试突击版》来啦!GitHub 上标星 98.1k,帮你成功上岸!

学弟学妹们,学会霍夫曼编码后,再也不用担心网络带宽了!

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qing_gee/article/details/115456714

智能推荐

〖Python 数据库开发实战 - Python与MySQL交互篇④〗- 数据库连接池技术-程序员宅基地

文章浏览阅读4.1w次,点赞122次,收藏88次。上一章节我们利用了事务机制进行了数据的写入(执行了 INSERT 语句)。"增、删、改、查"这四个操作,只做了 "查询" 与 "添加","删除" 与 "修改" 的实验还没有做。先别着急,接下来我们先学习一下 "连接池技术",然后再去练习 "删除" 与 "修改" 的实验也不迟。............

Windows安装word2vec的那些坑_word2vec安装失败-程序员宅基地

文章浏览阅读2.5k次。打开命令窗口,执行pip install word2vec,如图:ERROR: Command errored out with exit status 1: command: 'e:\python\python.exe' -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\\TEMP\\pip-install-x..._word2vec安装失败

jsp在页面获取不到值的方法_在jsp文件中requestscoped读取不到元素-程序员宅基地

文章浏览阅读6.1k次,点赞6次,收藏16次。自己在做项目的时候,在jsp页面通。过${xxx}获取不到值,困扰了自己好久。自己jsp页面如下:<input id="uuid" type="hidden" value="${user.uId}" name="userId"/>controller如下: @RequestMapping(value = "/checkLogin",method = Reques_在jsp文件中requestscoped读取不到元素

Objective-C使用form方式提交json_oc post form-程序员宅基地

文章浏览阅读531次。NSString *urlStr = @"http://localhost:8080/datainterface/interfacename"; NSMutableURLRequest *jsonRequest = [[NSMutableURLRequest alloc] init]; [jsonRequest setURL:[NSURL URLWithString:ur_oc post form

KMS激活理论_kms csdn-程序员宅基地

文章浏览阅读915次。如果要在同一台KMS服务器上激活多个产品(如Office 2010和Windows 7),则需要同时安装并激活Windows KMS主机密钥。例如,当用户A安装完Office 2010后,6、KMS激活之后并非永久有效,KMS客户端必需在180之内再次连接到KMS服务器上对产品进行激活。1、Office 2007的批量授权版本是不需要激活,安装完成便可以正常使用的,但从Office 2010开始,激活的180天之内,KMS 客户端必需主动联系到KMS服务器进行重新激活,激活完成后可以再使用180天。_kms csdn

Visual Studio Team Foundation Server 2010_microsoft visual studio team foundation server 201-程序员宅基地

文章浏览阅读1w次。当前的工作用到了TFS,从没玩过,赶紧补习下,推荐下载地址:http://download.csdn.net/detail/wujiandao/4128032 Getting Started with Visual Studio Application Lifecycle ManagementVisual Studio 2010Other Ver_microsoft visual studio team foundation server 2010

随便推点

什么是知识图谱?有哪些典型应用?终于有人讲明白了_知识图谱的典型应用包括,传统搜索机器问答社交网络-程序员宅基地

文章浏览阅读6.2k次,点赞7次,收藏33次。知识图谱?有哪些典型应用?01 知识图谱背景1. 什么是知识2. 什么是图谱02 知识图谱的定义03 知识图谱的典型应用1. 医疗领域2. 金融投资领域3. 政府管理和安全领域4. 电商领域5. 聊天机器人领域01 知识图谱背景在给出知识图谱的定义之前,我们先分开讨论一下什么是知识,什么是图谱。1. 什么是知识首先看一下什么是知识。有读者可能会提出这样的问题,在大数据时代,人类拥有海量的数据,这是不是代表人类可以随时随地利用无穷无尽的知识呢?答案是否定的。知识是人类在实践中认识客观世界(包括人类_知识图谱的典型应用包括,传统搜索机器问答社交网络

soldworks文件在线预览_solidworks在线预览-程序员宅基地

文章浏览阅读4.1k次。今天很多工程师都使用不同的CAD软件,以至于产生了不同格式的CAD格式文件,因此所有人都难以互换,其中主流的CAD软件有:PTC Creo,Siemens NX,CATIA,SolidWorks,Autodesk Inventor等,如果要向下游进行传递或是需要在线预览下车间等,则需要统一轻量化处理后方可传递或是在线预览,经过近三年的时间探索,目前实现了几种主流CAD文件的轻量化处理,处理后的文件可以在线预览或是传递给下游系统,如有需要可以扫描下方且交流,其中sldprt文件在线预览如下:..._solidworks在线预览

用户登录状态记录cookie被禁用 怎么保存在html中,怎样将用户名和密码保存到Cookie中? (html部分)...-程序员宅基地

文章浏览阅读398次。在网站中,我们经常看到每当我们准备登陆时,网页询问我们是否保存用户名和密码,以便下次登陆时不用再次输入。诸如此类的功能如何实现哪?经过两天的研究,终于有了收获!现将我的经验与大家分享。在网页中记录用户的信息通常有如下几种方式:Session、Cookie、以及.Net环境下的ViewState等。比较起来,Session将用户的信息暂存在内存中,除非用户关闭网页,否则信息将一直有效。所以,用Ses..._cookie无法使用时如何保存用户信息

php pdo mysql_PHP中利用PDO_mysql操作MySQL数据库-程序员宅基地

文章浏览阅读559次。在刚刚接触PHP时,曾遇到过这样一个坑,就是在PHP7.0版本中无法使用mysql连接数据库,当时只好降级PHP版本来通过mysql来连接数据库(很无奈的做法),但作为一个与时俱进的程序员,必须学习新的技术才能保持竞争力,所以今天就介绍一下利用PDO_mysql连接MySQL,这也是PHP新版本推荐使用的一个扩展。PDO_mysql操作在php.ini中开启PDO_mysql扩展//取消注释ext..._pat pdo_mysql

vue 中数组中的某个对象的属性发生变化,视图不更新如何解决?_vue改变数组或对象视图没更新-程序员宅基地

文章浏览阅读1.8k次。第一种是数组的值改变,在改变数组的值的时候使用索引值去更改某一项,这样视图不会实时更新,这种情况是因为直接通过索引去改变数组,vue对象监听不到他的变化,所以没有更新;使用vue的变异方法pop(),push(),shift(),unshift(),revese(),sort(),splice()等方法也会触发视图更新。1.利用vue.set(object,key,val):例:vue.set(vm.obj,'k1','v1');2.利用Object.assign({},this.obj)创建新对象;_vue改变数组或对象视图没更新

系统性能优化的十大策略(强烈推荐,建议收藏)-程序员宅基地

文章浏览阅读654次。点击上方“芋道源码”,选择“设为星标”管她前浪,还是后浪?能浪的浪,才是好浪!每天 10:33更新文章,每天掉亿点点头发...源码精品专栏原创 | Java 2021超神之路,很肝~中文详细注释的开源项目RPC 框架 Dubbo 源码解析网络应用框架 Netty 源码解析消息中间件 RocketMQ 源码解析数据库中间件 Sharding-JDBC 和 MyCAT 源码解析作业调度中间件 E..._系统级的优化