二叉堆与二叉堆的构建
生活随笔
收集整理的這篇文章主要介紹了
二叉堆与二叉堆的构建
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
什么是二叉堆?
二叉堆本質上是一種完全二叉樹,它分為兩個類型:
二叉堆的根節點叫做堆頂。
? ? 最大堆和最小堆的特點決定了:最大堆的堆頂是整個堆中的最大元素;最小堆的堆頂是整個堆中最小元素。
構建二叉堆
對于二叉堆,有如下幾種操作:
這幾種操作都基于堆的自我調整。所謂堆的自我調整,就是把一個不符合堆性質的完全二叉樹,調整成一個堆。
代碼實現
????在展示代碼之前,需要明確一點:二叉堆雖然是一個完全二叉樹,但他的存儲方式并不是鏈式存儲,而是順序存儲。換句話說,二叉堆的所有節點都存儲在數組中。
? ? 假設父節點的下標是parent,那么它的做孩子下標就是2*parent+1;右孩子下標就是2*parent+2。
代碼實現如下:
import java.util.Arrays;public class BinaryHeap {public static void main(String[] args) {int[] array = new int[]{1, 3, 2, 6, 5, 7, 8, 9, 10, 0};upAjust(array);System.out.println(Arrays.toString(array));array = new int[]{7, 1, 3, 10, 5, 2, 8, 9, 6};buildHeap(array);System.out.println(Arrays.toString(array));}/*** 最小堆的"上浮"調整, 只對最后一個葉子節點上浮** @param array 待調整的堆*/private static void upAjust(int[] array) {int childIndex = array.length - 1; // 最后一個葉子節點int parentIndex = (childIndex - 1) / 2; // 最后一個非葉子節點// temp保存插入的葉子結點值,用于最后的賦值int temp = array[childIndex];while (childIndex > 0 && temp < array[parentIndex]) {//無需真正交換,單項賦值即可array[childIndex] = array[parentIndex];childIndex = parentIndex;parentIndex = (parentIndex - 1) / 2;}array[childIndex] = temp;}/*** 最小堆"下沉"調整** @param array 待調整的堆* @param parentIndex 要"下沉"的父節點* @param length 堆的有效大小*/public static void downAdjust(int[] array, int parentIndex, int length) {// temp保存父節點值, 用于最后的賦值int temp = array[parentIndex];int childIndex = 2 * parentIndex + 1;while (childIndex < length) {// 如果有右孩子, 且右孩子小于左孩子的值,則定位到右孩子if (childIndex + 1 < length && array[childIndex + 1] < array[childIndex]) {childIndex++;}// 如果父節點小于任何一個孩子的值,則直接跳出if (temp <= array[childIndex]) {break;}// 無需真正交換,單項賦值即可array[parentIndex] = array[childIndex];parentIndex = childIndex;childIndex = 2 * childIndex + 1;}array[parentIndex] = temp;}/*** 構建最小堆** @param array 待調整的堆*/public static void buildHeap(int[] array) {// 從最后一個非葉子節點開始,一次做"下沉"調整for (int i = (array.length - 2) / 2; i >= 0; i--) {downAdjust(array, i, array.length);}}}代碼中有一個優化的點,就是在父節點與孩子節點做連續交換時,不一定要真的交換,只需要先把交換一方的值存入temp變量,做單向覆蓋,循環結束后,再把temp的值存入交換后的最終位置即可。
總結
以上是生活随笔為你收集整理的二叉堆与二叉堆的构建的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: springboot实现多线程servi
- 下一篇: Apache Flink 零基础入门(一