【问题标题】:Why is element zero of a heap array not used?为什么不使用堆数组的零元素?
【发布时间】:2026-01-14 21:25:01
【问题描述】:

这是我对具有任意值的堆开始的粗略草图

 0   1    2    3    4    5    6    7    8    9   ...
[-] [10] [14] [15] [22] [21] [24] [23] [44] [30] ...

为什么必须将array[0] 中的元素始终设置为null?
或者为什么我们不应该使用它?

【问题讨论】:

  • 你从哪里得到不应该使用数组元素零的想法?
  • 谁说array[0]必须为空?
  • 你在说什么实现?

标签: java heap


【解决方案1】:

有几种方法可以将二叉堆表示为数组。

有一种使用零元素的方法;还有一种方法可以使用元素零:

  1. 根是元素0;元素n 的子元素是元素2n+12n+2
  2. 根是元素 1;元素n 的子元素是元素2n2n+1

两者都不比另一个更“正确”。前者更适合使用zero-based arrays 的编程语言,而后者更适合使用one-based arrays 的语言。

您似乎遇到了使用第二种方法的实现。由于所讨论的语言 Java 使用从零开始的数组,因此元素零存在但未被使用。

【讨论】:

  • 嗯,第二种方法浪费了非常好的内存而没有任何好处,所以我想说这使它不如第一种。不过你可能是对的
  • @Voo:如果语言使用基于 1 的数组,则第二种方法不会浪费。在那里,array[1] 是第一个元素,没有 array[0],没有任何浪费。
  • @Philip 是的,如果我们谈论的是这样一种语言,是的。但上次我检查 java 使用了数组索引的明智方法;)更严重:我的评论是关于答案的早期版本 - 我同意的更新版本现在不太好(你可以查找旧的单击“已编辑”旁边的日期即可获得答案的版本)
  • 我想指出的是,使用从一开始的索引,操作PARENT=[n/2]LEFTCHILD=2n可以通过位移有效地实现。
  • @Max 你也可以通过在移位之前减去 1 来将位移到基于 0 的索引,像这样(n - 1) >> 1
【解决方案2】:

这真的归结为数学家和软件工程师之间的文化差异。

  • 通常,数学家使用 1(一)作为向量的第一个元素或矩阵的第一列/行的索引。

  • 出于多种(合理的)原因,软件工程师使用 0(零)代替。所有现代主流编程语言也是如此。

您可能已经在某些文本中遇到过对堆数据结构/算法的描述,该描述是由更喜欢“数学”约定而不是“软件工程”约定的人编写的。然后,您已经用 Java 编写了算法,该算法(与大多数现代 PL 一样)使用从零开始的数组。

如果您觉得这令人不安,只需修改您的代码以从索引值中减去 1。


请注意,软件工程领域也有例外:

  • FORTRAN、COBOL、RPG 和其他一些编程语言 - 请参阅 Wikipedia
  • JDBC 中的参数和列编号。
  • DOM API 中的节点编号。

(我提到的所有合理原因归结为这样一个事实,即如果零是第一个元素的索引,则涉及索引计算的算法通常更简单。This article 解释了它。)

【讨论】:

    【解决方案3】:

    或者为什么我们不应该使用它?

    如果不使用它,那么您的索引将从 1 开始,您可以只使用 教科书 算法。

    大多数算法书籍都以1 而不是0 开头描述算法。

    您可以使用元素0,但是您必须将索引修改为@aix 答案。

    有些人觉得不使用0是浪费空间。
    其他人认为不使用0 会导致代码更具可读性。

    任君挑选

    【讨论】: