参考:https://www.cnblogs.com/malw/p/10542557.html
堆排序是基于完全二叉树实现的,在将一个数组调整成一个堆的时候,关键之一的是确定最后一个非叶子节点的序号,这个序号为n/2-1,n为数组的长度。但是为什么呢?
可以分两种情形考虑:
①堆的最后一个非叶子节点若只有左孩子
②堆的最后一个非叶子节点有左右两个孩子
完全二叉树的性质之一是:如果节点序号为i,在它的左孩子序号为2*i+1,右孩子序号为2*i+2。
对于①左孩子的序号为n-1,则n-1=2*i-1,推出i=n/2-1;
对于②左孩子的序号为n-2,在n-2=2*i-1,推出i=(n-1)/2-1;右孩子的序号为n-1,则n-1=2*i+2,推出i=(n-1)/2-1;
很显然,当完全二叉树最后一个节点是其父节点的左孩子时,树的节点数为偶数;当完全二叉树最后一个节点是其父节点的右孩子时,树的节点数为奇数。
根据java语法的特征,整数除不尽时向下取整,则若n为奇数时(n-1)/2-1=n/2-1。
因此对于②最后一个非叶子节点的序号也是n/2-1。
得证。
显然序号是从0开始的。