日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

二叉堆与二叉堆的构建

發布時間:2024/9/16 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 二叉堆与二叉堆的构建 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

什么是二叉堆?

二叉堆本質上是一種完全二叉樹,它分為兩個類型:

  • 最大堆:任何一個父節點的值,都大于或等于它左、右孩子節點的值。
  • 最小堆:任何一個父節點的值,都小于或等于它左、右孩子節點的值。
  • 二叉堆的根節點叫做堆頂。

    ? ? 最大堆和最小堆的特點決定了:最大堆的堆頂是整個堆中的最大元素;最小堆的堆頂是整個堆中最小元素。

    構建二叉堆

    對于二叉堆,有如下幾種操作:

  • 插入節點。
  • 刪除節點。
  • 構建二叉堆。也就是把一個無序的完全二叉樹調整為二叉堆,本質上就是讓所有非葉子節點依次“下沉”。
  • 這幾種操作都基于堆的自我調整。所謂堆的自我調整,就是把一個不符合堆性質的完全二叉樹,調整成一個堆。

    代碼實現

    ????在展示代碼之前,需要明確一點:二叉堆雖然是一個完全二叉樹,但他的存儲方式并不是鏈式存儲,而是順序存儲。換句話說,二叉堆的所有節點都存儲在數組中。

    ? ? 假設父節點的下標是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的值存入交換后的最終位置即可。

    總結

    以上是生活随笔為你收集整理的二叉堆与二叉堆的构建的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。