下面小編就為大家帶來一篇老生常談比較排序之堆排序。小編覺得蠻不錯的,現在就分享給大家,也給大家做個參考。一起跟著小編過來看看吧
對於堆排序會涉及一些完全二元樹知識。對於待排序列{10, 2, 11, 8, 7},把它看成是一顆完全二元樹,如下圖所示。
堆分為大根堆和小根堆:大根堆表示每個根節點均大於其子節點(L(i) >= L(2i) && L(i) >= L(2i + 1)),小根堆表示每個根節點均小於其子節點(L(i)
本文將以大根堆的建構作為範例進行講解。
堆排序的第一步-建構初始堆。如何建構初始堆呢?根據定義,關鍵點在於每個根節點。觀察上述待排序列的完全二元樹,不難發現存在節點2和節點10有子節點,它們是需要關注的節點。
如何定位節點2呢?發現它是葉節點,或最後一個節點的父節點,根據完全二元樹的性質可知,除根節點外任意節點的父節點的編號為⌊n / 2⌋。已知n = 5,易知節點2的編號為⌊5 / 2⌋ = ②。比較它與左右子節點的大小並調整。
最後剩下根節點10,已知節點2的編號為②,② - 1 = ①即得到根節點10的編號。比較它與左右子節點的大小並調整。
調整完畢後發現已經構成了一個“大根堆”,範例中的待排序列較為簡單,再給出一個較為複雜的待排序列,觀察其建構大根堆的過程。對於待排序列{53, 17, 78, 09, 45, 65, 87, 32},將它看成一顆完全二元樹。
同樣我們來看它所需要關注的節點有哪些。
根據第一個例子,我們很容易定位節點09的編號為⌊8 / 2⌋ = ④,節點78的編號為④ - 1 = ③… …,依次類推,發現了一定的規律,即需要調整的節點位置從⌊n / 2⌋
#開始依序遞減直到根節點①結束(
可以看到將根節點與最後一個節點呼喚後,待排序列的最大值已經放到了數組的最後一個位置{……, 87},此時完成了第一趟排序,但這第一趟排序還沒結束,此時除節點87外,其餘節點並不符合大根堆的條件,所以需要將其餘節點調整為大根堆。排序過程不再給出,Java和Python3的程式碼實作如下。
Java
package com.algorithm.sort.heap; import java.util.Arrays; /** * 堆排序 * Created by yulinfeng on 6/20/17. */ public class Heap { public static void main(String[] args) { int[] nums = {53, 17, 78, 09, 45, 65, 87, 32}; nums = heapSort(nums); System.out.println(Arrays.toString(nums)); } /** * 堆排序 * @param nums 待排序数组序列 * @return 排好序的数组序列 */ private static int[] heapSort(int[] nums) { for (int i = nums.length / 2 - 1; i >= 0; i--) { heapAdjust(nums, i, nums.length); } for (int i = nums.length - 1; i > 0; i--) { int temp = nums[i]; nums[i] = nums[0]; nums[0] = temp; heapAdjust(nums, 0, i); } return nums; } /** * 调整堆 * * @param nums 待排序序列 * @param parent 待调整根节点 * @param length 数组序列长度 */ private static void heapAdjust(int[] nums, int parent, int length) { int temp = nums[parent]; int childIndex = 2 * parent + 1; //完全二叉树节点i从编号1开始的左子节点位置在2i,此处数组下标从0开始,即左子节点所在数组索引位置为:2i + 1 while (childIndex < length) { if (childIndex + 1 < length && nums[childIndex] < nums[childIndex + 1]) { childIndex++; //节点有右子节点,且右子节点大于左子节点,则选取右子节点 } if (temp > nums[childIndex]) { break; //如果选中节点大于其子节点,直接返回 } nums[parent] = nums[childIndex]; parent = childIndex; childIndex = 2 * parent + 1; //继续向下调整 } nums[parent] = temp; } }
Python3
#堆排序 def heap_sort(nums): for i in range(int(len(nums) / 2 - 1), -1, -1): heap_adjust(nums, i, len(nums)) for i in range(len(nums) - 1, -1, -1): temp = nums[i] nums[i] = nums[0] nums[0] = temp heap_adjust(nums, 0, i) return nums #调整堆 def heap_adjust(nums, parent, length): temp = nums[parent] childIndex = 2 * parent + 1 while childIndex < length: if childIndex + 1 < length and nums[childIndex] < nums[childIndex + 1]: childIndex += 1 if temp > nums[childIndex]: break nums[parent] = nums[childIndex] parent = childIndex childIndex = 2 * parent + 1 nums[parent] = temp nums = [53, 17, 78, 09, 45, 65, 87, 32] nums = heap_sort(nums) print(nums)
以上這篇老生常談比較排序之堆排序就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
以上是JAVA排序之堆排序的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本文討論了使用Maven和Gradle進行Java項目管理,構建自動化和依賴性解決方案,以比較其方法和優化策略。

本文使用Maven和Gradle之類的工具討論了具有適當的版本控制和依賴關係管理的自定義Java庫(JAR文件)的創建和使用。

本文討論了使用咖啡因和Guava緩存在Java中實施多層緩存以提高應用程序性能。它涵蓋設置,集成和績效優勢,以及配置和驅逐政策管理最佳PRA

本文討論了使用JPA進行對象相關映射,並具有高級功能,例如緩存和懶惰加載。它涵蓋了設置,實體映射和優化性能的最佳實踐,同時突出潛在的陷阱。[159個字符]

Java的類上載涉及使用帶有引導,擴展程序和應用程序類負載器的分層系統加載,鏈接和初始化類。父代授權模型確保首先加載核心類別,從而影響自定義類LOA

本文解釋了用於構建分佈式應用程序的Java的遠程方法調用(RMI)。 它詳細介紹了接口定義,實現,註冊表設置和客戶端調用,以解決網絡問題和安全性等挑戰。

本文詳細介紹了用於網絡通信的Java的套接字API,涵蓋了客戶服務器設置,數據處理和關鍵考慮因素,例如資源管理,錯誤處理和安全性。 它還探索了性能優化技術,我

本文詳細介紹了創建自定義Java網絡協議。 它涵蓋協議定義(數據結構,框架,錯誤處理,版本控制),實現(使用插座),數據序列化和最佳實踐(效率,安全性,維護


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境

SublimeText3漢化版
中文版,非常好用

Atom編輯器mac版下載
最受歡迎的的開源編輯器