13.1:堆的heapify下沉过程

13.1:堆的heapify下沉过程

 

现在的要求是:

  此时在大根堆上,将最大的数max返回,剩下的数自动按照大根堆的要求重新建成新的大根堆?

 

操作思路:

       [ 8  7  0  1  6  ]

  下标: 0  1  2  3  4

我们知道大根堆上最大值一定在index = 0位置上,所以给用户直接返回max = 8没问题;

返回之前要将这个数8删除??

通过heapSize管着

此时 heapSize = 5,有5个数。

用堆上最后一个数去替换0位置的数,也可以交换。返回max后,heapSize--,一定要减减,heapSize = 4;

 

               [ 6  7  0  1  8  ]

  下标: 0  1   2   3       heapSize = 4,4位置的8就被废弃,

  由heapSize管着,与左孩子2*i+1进行比较,如果左孩子越界,右孩子肯定越界。

  通过heapSize来控制堆的长度

 

            [ 6  7  0  1  8  ]

  下标: 0  1   2   3                此时破坏了堆的规则,需要从0位置开始到3位置,将堆调对。 

 

heapify思路:

      1、从0位置看它左、右两孩子,找到较大的孩子(如果左、右子树都比0位置数的大,找最大的那个),看是否比0位置的数大;

    2、如果较大的数比0位置数大,这个孩子上去,0位置的数下来;

    3、下来后,接着按照1和2的思路继续调整;

    4、直到这个数没有孩子了 或者 下沉到较大孩子干不过这个数了,调整结束;

       

 

 1         // 从index位置,往下看,不断的下沉
 2         // 停:较大的孩子都不再比index位置的数大;已经没孩子了
 3         private void heapify(int[] arr, int index, int heapSize) {
 4             int left = index * 2 + 1;
 5             while (left < heapSize) { // 如果有左孩子,有没有右孩子,可能有可能没有!
 6                 
 7                 // 把较大孩子的下标,给largest
 8                 //右孩子不越界并且右孩子大于左孩子,largest变量指向右孩子的在数组中的位置,否则左孩子的位置
 9                 int largest = left + 1 < heapSize && arr[left + 1] > arr[left] ? left + 1 : left;
10                 
11                 //拿左、右孩子中更大的那个,和arr[index]位置的数进行比较
12                 //largest记录这两个数中更大的那个数的下标位置
13                 largest = arr[largest] > arr[index] ? largest : index;
14                 if (largest == index) {     //是自己那肯定不要交换
15                     break;
16                 }
17                 // index和较大孩子,要互换
18                 swap(arr, largest, index);  //不是自己那肯定要交换
19                 index = largest;            //交换后,变更index位置
20                 left = index * 2 + 1;       //交换后,变更新left位置,继续while循环。
21             }
22         }

 

 

 

 

  

 

posted @ 2022-05-16 11:26  yzmarcus  阅读(52)  评论(0)    收藏  举报