PriorityQueue 是线性结构吗?90%的人都搞错了!

PriorityQueue 是线性结构吗?90%的人都搞错了!

宏伟壮观的天坛

文章首发于「陈树义」公众号及个人博客 shuyi.tech

其实这个问题的完整描述是:Java 中的 PriorityQueue 实现,其数据的逻辑结构是线性结构吗?其数据的物理结构又是什么?

估计很多人的答案是:PriorityQueue 是线性结构,因为 PriorityQueue 是优先级队列的实现,队列不就是线性结构的吗?但在PriorityQueue 的实现中,其数据的逻辑结构是树形结构,其物理结构是顺序存储结构。

要弄明白这个问题,我们必须先弄明白什么是数据的逻辑结构,什么是数据的物理结构。

顾名思义,数据的逻辑结构指的是数据是怎么组织起来的,数据的物理结构指的是数据是怎么存储的。 数据的逻辑结构与物理结构,是数据结构两个非常重要的要素。但你知道数据有几种逻辑结构、几种物理结构吗?

数据的逻辑结构

数据的逻辑结构指的是数据是如何组织起来的,反映数据元素之间的逻辑关系,它更加贴近于现实。 例如现实生活中树干与树叶就是树形结构,排队的队伍就是线性关系。

数据的逻辑结构一般有四种,分别是:线性结构、集合结构、树形结构、网络结构。 其中,我们把集合、树形结构、网络结构统称为非线性结构。

线性结构

线性结构指的是数据结构中的元素存在一对一的相互关系。 例如:数组是一种线性结构,其下标与元素一一对应。链表也是一种线性结构,其元素之间是一个接着一个的。生活中有很多类似的例子,例如排队买票的队伍就是一个线性结构。超市里排布整齐的商品,也是一个线性结构。

逻辑结构之线性结构

集合结构

集合结构指的是元素之间除了「同属一个集合」的关系之外,再无其他关系。 例如数学中的整数就是一个集合,所有小数也是一个集合。

逻辑结构之集合

树形结构

树形结构指的是元素存在一对多的关系。 例如水果有香蕉、草莓、西瓜等,这种逻辑结构就是树形结构。

逻辑结构之线树形结构

网络结构

网络结构指的是元素存在多对多的关系。 网络结构也叫做网状结构,它是多对多的关系。比如城市的交通网络,每栋房子与其他房子都有许多条路。

逻辑结构之网络结构

数据的物理存储结构

数据的物理结构指的是数据是如何存储的,反映数据的存储结构。 数据的存储结构分为四种:顺序存储、链式存储、索引存储、散列存储。 一般我们将这四种物理结构分为顺序存储结构与非顺序存储结构。顺序存储是顺序存储结构,链式存储、索引存储、散列存储均属于非顺序存储结构。

数据的顺序存储结构的特点是:借助元素的相对位置来表示数据元素之间的逻辑关系。非顺序存储的特点是:借助指示元素存储地址的指针表示数据元素之间的逻辑关系。

注:有些朋友说数据的物理存储结构只有顺序存储、链式存储两种,索引存储和散列存储是不存在的。对此,后续我专门写篇文章来聊聊这个事情。

顺序存储

顺序存储指的是数据在内存当中是按照顺序存储的,逻辑结构上相邻的元素在物理结构上也是相邻的。Java 中的 ArrayList 就是通过顺序存储的方式实现的。

物理结构之顺序存储

链式存储

链式存储指的是元素之间的逻辑顺序,并不是通过内存顺序来分配的,而是通过一个引用组织起来的。也就是说,逻辑上相邻的元素,在物理存储位置上是不相邻的。Java 中的 LinkedList 就是通过链式存储的方式实现的。

物理结构之链式存储

索引存储

索引存储指的是元素之间的逻辑关系,是通过一张索引表来存储的。这张索引表有很多个索引项,每个索引项存储两个信息:关键字、数据存储地址。我们通过关键字可以找到对应的数据存储地址。这就像书籍的目录一样,关键字就是章节名,数据存储地址就是页码。我们通过章节名可以快速地找到对应的页码,从而快速地找到书籍对应内容。

物理结构之索引存储

散列存储

散列存储也称之为哈希存储,其与索引存储非常类似,都是通过索引值以及对应的值来实现快速查找。唯一不同的区别是,索引存储会对索引值进行哈希。应该说散列存储是索引存储的一种更加复杂的实现。

物理结构之散列存储

辨别思路

看到这里,我们对数据的逻辑结构、物理结构已经有了基本的认识,也知道它们的常见种类。那我们到底如何去判断它们是属于哪种逻辑结构、哪种物理结构呢?

拿 Java 中对于优先级队列的 PriorityQueue 实现为例。通过阅读源码我们得知其底层使用了二叉堆实现,而二叉堆本身其实就是一颗二叉树。即对于 PriorityQueue 来说,其数组最终是通过下图这种逻辑结构组织起来的,因此 PriorityQueue 的逻辑结构是树形结构。

PriorityQueue的逻辑结构

从 PriorityQueue 的源码,我们可以知道 PriorityQueue 的数据最终是通过一个对象数组存储的,而数组的物理结构是顺序存储的。因此对于 PriorityQueue 来说,其物理结构是顺序存储结构。

PriorityQueue的类成员变量

通过 PriorityQueue 这个例子,我们可以总结出判断数据的逻辑结构、物理结构的思路:判断逻辑结构,要看数据是如何组织起来的。要判断物理结构,则是要看数据最终是如何存储的。

如果对 PriorityQueue 的源码实现感兴趣,可以阅读:集合系列 Queue(九):PriorityQueue - 陈树义的博客

我们再用这个办法来判断一下 TreeMap 这个类。

TreeMap 是 Java 中非常经典的实现,其底层是基于红黑树的实现,即其最终会将所有数据组织成一颗红黑树,因此 TreeMap 的逻辑结构是树形结构。通过阅读 TreeMap 的源码,我们知道 TreeMap 的数据最终是通过 Entry 这个类存储的,因此 TreeMap 的物理结构是链式存储结构。

TreeMap的类成员变量

如果对 TreeMap 的源码实现感兴趣,可以阅读:集合系列 Map(十五):TreeMap - 陈树义的博客

最后我们拿比较复杂的 LinkedBlockingQueue 来分析一下。

很多人会说队列就是一种特殊的数组,而数组是顺序存储的,因此队列就是顺序存储的。如果将这个结论套用在 LinkedBlockingQueue 上,那是否可以得出同样的结论,即 LinkedBlockingQueue 也是顺序存储的呢?

前面我们说过:不要用直觉去判断,而要根据定义去判断。 即判断数据的逻辑结构、物理结构的思路是:判断逻辑结构,要看数据是如何组织起来的。要判断物理结构,则是要看数据最终是如何存储的。

LinkedBlockingQueue 是 Java 中的阻塞队列实现,其最终会将数组组织成一个队列,因此其逻辑结构上属于线性表。通过阅读源码,我们可以知道 LinkedBlockingQueue 的元素是存储在 Node 节点上的,因此 LinkedBlockingQueue 的物理结构属于链式存储。

LinkedBlockingQueue的类成员变量

总结

本文一开始通过 PriorityQueue 的例子,引入了逻辑结构与物理结构这个话题。接着介绍了四种逻辑结构:线性表、集合、树状结构、网络结构。

数据结构之四种逻辑结构

紧接着介绍了四种物理存储结构,分别是:顺序存储、链式存储、索引存储、哈希存储。

数据结构之四种物理结构

接着通过 PriorityQueue 的例子,得出判断数据的逻辑结构和物理结构的思路:判断逻辑结构,要看数据是如何组织起来的。要判断物理结构,则是要看数据最终是如何存储的。 最后再通过 TreeMap 和 LinkedBlockingQueue 这两个例子,带大家实践判断思路。

看到这里文章就结束了,如果你喜欢本篇文章,欢迎点赞、在看、转发、留言支持我,我们下次见~

参考资料

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,284评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,115评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,614评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,671评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,699评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,562评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,309评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,223评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,668评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,859评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,981评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,705评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,310评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,904评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,023评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,146评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,933评论 2 355

推荐阅读更多精彩内容