基礎堆排序(Java 實例代碼)

目錄

?

基礎堆排序

一、概念及其介紹

二、適用說明

三、過程圖示

四、Java 實例代碼

src/runoob/heap/Heapify.java 文件代碼:


?

基礎堆排序

一、概念及其介紹

堆排序(Heapsort)是指利用堆這種數據結構所設計的一種排序算法。

堆是一個近似 完全二叉樹的結構,并同時滿足堆積的性質:即子結點的鍵值或索引總是小于(或者大于)它的父節點。

二、適用說明

我們之前構造堆的過程是一個個數據調用 insert 方法使用 shift up 逐個插入到堆中,這個算法的時候時間復雜度是 O(nlogn),本小節介紹的一種構造堆排序的過程,稱為 Heapify,算法時間復雜度為 O(n)

三、過程圖示

完全二叉樹有個重要性質,對于第一個非葉子節點的索引是 n/2 取整數得到的索引值,其中 n 是元素個數(前提是數組索引從 1 開始計算)。

?

8533aeaabb8bcf09d2f2cd103cd9ff0e.png

索引 5 位置是第一個非葉子節點,我們從它開始逐一向前分別把每個元素作為根節點進行 shift down 操作滿足最大堆的性質。

索引 5 位置進行 shift down 操作后,22 和 62 交換位置。

?

5e791e13029e315ffdf601d7dac7837f.png

對索引 4 元素進行 shift down 操作

?

78f5380da0c82c652b1bc821a8b0236e.png

對索引 3 元素進行 shift down 操作

?

d88f077f5f376a8aeaf89f450e7d57ff.png

對索引 2 元素進行 shift down 操作

?

61f8df73255048aae76de8b24454c38e.png

最后對根節點進行 shift down 操作,整個堆排序過程就完成了。

?

dc779b8bcc78fd27af078d7b2f4d7819.png

四、Java 實例代碼

源碼包下載:Downloadhttps://www.runoob.com/wp-content/uploads/2020/09/runoob-algorithm-Heapify.zip

src/runoob/heap/Heapify.java 文件代碼:

package runoob.heap;

import runoob.sort.SortTestHelper;

/**
?* 用heapify進行堆排序
?*/
public class Heapify<T extends Comparable> {

? ? protected T[] data;
? ? protected int count;
? ? protected int capacity;

? ? // 構造函數, 通過一個給定數組創建一個最大堆
? ? // 該構造堆的過程, 時間復雜度為O(n)
? ? public Heapify(T arr[]){

? ? ? ? int n = arr.length;

? ? ? ? data = (T[])new Comparable[n+1];
? ? ? ? capacity = n;

? ? ? ? for( int i = 0 ; i < n ; i ++ )
? ? ? ? ? ? data[i+1] = arr[i];
? ? ? ? count = n;
? ? ? ? //從第一個不是葉子節點的元素開始
? ? ? ? for( int i = count/2 ; i >= 1 ; i -- )
? ? ? ? ? ? shiftDown(i);
? ? }
? ? // 返回堆中的元素個數
? ? public int size(){
? ? ? ? return count;
? ? }
? ? // 返回一個布爾值, 表示堆中是否為空
? ? public boolean isEmpty(){
? ? ? ? return count == 0;
? ? }
? ? // 像最大堆中插入一個新的元素 item
? ? public void insert(T item){
? ? ? ? assert count + 1 <= capacity;
? ? ? ? data[count+1] = item;
? ? ? ? count ++;
? ? ? ? shiftUp(count);
? ? }
? ? // 從最大堆中取出堆頂元素, 即堆中所存儲的最大數據
? ? public T extractMax(){
? ? ? ? assert count > 0;
? ? ? ? T ret = data[1];
? ? ? ? swap( 1 , count );
? ? ? ? count --;
? ? ? ? shiftDown(1);
? ? ? ? return ret;
? ? }
? ? // 獲取最大堆中的堆頂元素
? ? public T getMax(){
? ? ? ? assert( count > 0 );
? ? ? ? return data[1];
? ? }


? ? // 交換堆中索引為i和j的兩個元素
? ? private void swap(int i, int j){
? ? ? ? T t = data[i];
? ? ? ? data[i] = data[j];
? ? ? ? data[j] = t;
? ? }

? ? //********************
? ? //* 最大堆核心輔助函數
? ? //********************
? ? private void shiftUp(int k){

? ? ? ? while( k > 1 && data[k/2].compareTo(data[k]) < 0 ){
? ? ? ? ? ? swap(k, k/2);
? ? ? ? ? ? k /= 2;
? ? ? ? }
? ? }

? ? private void shiftDown(int k){

? ? ? ? while( 2*k <= count ){
? ? ? ? ? ? int j = 2*k; // 在此輪循環中,data[k]和data[j]交換位置
? ? ? ? ? ? if( j+1 <= count && data[j+1].compareTo(data[j]) > 0 )
? ? ? ? ? ? ? ? j ++;
? ? ? ? ? ? // data[j] 是 data[2*k]和data[2*k+1]中的最大值

? ? ? ? ? ? if( data[k].compareTo(data[j]) >= 0 ) break;
? ? ? ? ? ? swap(k, j);
? ? ? ? ? ? k = j;
? ? ? ? }
? ? }

? ? // 測試 heapify
? ? public static void main(String[] args) {
? ? ? ? int N = 100;
? ? ? ? Integer[] arr = SortTestHelper.generateRandomArray(N, 0, 100000);
? ? ? ? Heapify<Integer> heapify = new Heapify<Integer>(arr);
? ? ? ? // 將heapify中的數據逐漸使用extractMax取出來
? ? ? ? // 取出來的順序應該是按照從大到小的順序取出來的
? ? ? ? for( int i = 0 ; i < N ; i ++ ){
? ? ? ? ? ? arr[i] = heapify.extractMax();
? ? ? ? ? ? System.out.print(arr[i] + " ");
? ? ? ? }

? ? ? ? // 確保arr數組是從大到小排列的
? ? ? ? for( int i = 1 ; i < N ; i ++ )
? ? ? ? ? ? assert arr[i-1] >= arr[i];
? ? }
}

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/35714.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/35714.shtml
英文地址,請注明出處:http://en.pswp.cn/news/35714.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Linux_5_Shell腳本編程

目錄 1 基礎1.1 程序組成1.2 程序編程風格1.3 編程語言1.4 編程邏輯處理方式 2 shell 腳本語言的基本結構2.1 shell腳本的用途2.2 shell腳本基本結構2.3 創建shell腳本過程2.4 腳本注釋規范2.5 第一個腳本2.6 腳本調試2.7 變量2.7.1 變量2.7.2 變量類型2.7.3 編程語言分類2.7.4…

【MAC】 M2 brew安裝 docker 運行失敗 解決

MAC 安裝 brew install --cask docker 之后一直顯示docker: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?. 網上看了一些文章 發現 這個不適用于M2 所以要從官網上下載 docker 安裝成功

C++ 動態規劃經典案例解析之最長公共子序列(LCS)_窺探遞歸和動態規劃的一致性

1. 前言 動態規劃處理字符相關案例中&#xff0c;求最長公共子序列以及求最短編輯距離&#xff0c;算是經典中的經典案例。 講解此類問題的算法在網上一抓應用一大把&#xff0c;即便如此&#xff0c;還是忍不住有寫此文的想法。畢竟理解、看懂都不算是真正掌握&#xff0c;唯…

多線程與并發編程面試題總結

多線程與并發編程 多線程 線程和進程的區別&#xff1f; 從操作系統層面上來講&#xff1a;進程(process)在計算機里有單獨的地址空間&#xff0c;而線程只有單獨的堆棧和局部內存空間&#xff0c;線程之間是共享地址空間的&#xff0c;正是由于這個特性&#xff0c;對于同…

Vim入門教程vimtutor1.7總結

vimtutor命令可以打開教程文檔 原文特別提示 ??? 特別提示&#xff1a;切記您要在使用中學習&#xff0c;而不是在記憶中學習 Vim模式 正常模式&#xff08;Normal Mode&#xff09;&#xff1a;默認模式&#xff0c;可以使用基礎命令進行操作命令模式&#xff08;Command…

阿里云國際版云服務器防火墻怎么設置呢?

入侵防御頁面為您實時展示云防火墻攔截流量的源IP、目的IP、阻斷應用、阻斷來源和阻斷事件詳情等信息。本文介紹了入侵防御頁面展示的信息和相關操作&#xff0c;下面和012一起來了解阿里云國際版云服務器防火墻設置&#xff1a; 前提條件 您需要先在防護配置頁面&#xff0c;開…

vscode debug python 帶參數

兩種方法 第一種&#xff1a; 1&#xff0c;側邊欄選擇運行和調試 2&#xff0c;請先創建一個launch.json文件 3&#xff0c;并選擇配置文件為python文件 此時你的工作目錄下會多一個目錄.vscode和該目錄下一個launch.json文件&#xff0c;該文件則配置了你的debug配置。在…

【報錯】ModuleNotFoundError: No module named ‘websocket‘

1 報錯 ModuleNotFoundError: No module named websocket 2 解決方法 pip install websocket 1 報錯 AttributeError: module websocket has no attribute enableTrace 2 分析 一般是由于websocket的依賴包沒有安裝造成的。websocket.enableTrace()方法是在websocket-cli…

C語言第十課----------------掃雷----------數組的經典練手題

作者前言 &#x1f382; ??????&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f382; &#x1f382; 作者介紹&#xff1a; &#x1f382;&#x1f382; &#x1f382;…

React構建的JS優化思路

背景 之前個人博客搭建時&#xff0c;發現頁面加載要5s才能完成并顯示 問題 React生成的JS有1.4M&#xff0c;對于個人博客服務器的帶寬來說&#xff0c;壓力較大&#xff0c;因此耗費了5S的時間 優化思路 解決React生成的JS大小&#xff0c;因為我用的是react-router-dom…

ORA-01034: ORACLE not available、ORA-27101: shared memory realm does not exist

發生緣由 學習 Oracle 的使用&#xff0c;結果關機之后重新使用 SQLPlus 發現無法登錄 -- windows server 2003 使用 sqlplus連接oracle報錯 C:\Documents and Settings\Adminstrator> sqlplus system/linxuan ORA-01034:ORACLE not available ORA-27101:shared memory r…

SAP FIORI Launchpad 403 forbidden error

問題&#xff1a; 在前臺輸入/N/UI2/FLP 瀏覽器顯示 403 forbidden 查閱資料得知 相關sicf 的服務未激活 note:3011106 檢查以下所有服務是否已在事務代碼 SICF 中激活&#xff1a; /default_host/sap/bc/ui2/nwbc/ /default_host/sap/bc/ui2/start_up /default_host/sap…

prometheus告警發送組件部署

一、前言 要實現Prometheus的告警發送需要通過alertmanager組件&#xff0c;當prometheus觸發告警策略時&#xff0c;會將告警信息發送給alertmanager&#xff0c;然后alertmanager根據配置的策略發送到郵件或者釘釘中&#xff0c;發送到釘釘需要安裝額外的prometheus-webhook…

模擬實現消息隊列(以 RabbitMQ 為藍本)

目錄 1. 需求分析1.1 介紹一些核心概念核心概念1核心概念2 1.2 消息隊列服務器&#xff08;Broker Server&#xff09;要提供的核心 API1.3 交換機類型1.3.1 類型介紹1.3.2 轉發規則&#xff1a; 1.4 持久化1.5 關于網絡通信1.5.1 客戶端與服務器提供的對應方法1.5.2 客戶端額外…

一站式FlinkSpark平臺解決方案——StreamX

隨著Flink&Spark生態的不斷完善&#xff0c;越來越多的企業選擇這兩款組件&#xff0c;或者其中之一作為離線&實時的大數據開發工具&#xff0c;但是在使用他們進行大數據的開發中我們會遇到一些問題&#xff0c;比如&#xff1a; 任務運行監控怎么處理&#xff1f;使…

【LangChain概念】了解語言鏈?:第2部分

一、說明 在LangChain的幫助下創建LLM應用程序可以幫助我們輕松地鏈接所有內容。LangChain 是一個創新的框架&#xff0c;它正在徹底改變我們開發由語言模型驅動的應用程序的方式。通過結合先進的原則&#xff0c;LangChain正在重新定義通過傳統API可以實現的極限。 在上一篇博…

一文讀懂!一年耗能堪比2個三峽電站的大數據中心,背后竟隱藏著這些秘密......

全國大數據中心1年的能耗規模相當于2個三峽電站一整年的發電量&#xff0c;這是為什么&#xff1f; 大數據中心每耗費1度電&#xff0c;只有一半用在了“計算”上面&#xff0c;其他的都應用在散熱、照明等方面到底是怎么回事&#xff1f; 為什么說在算力上每投入1元&#xff0…

【二】數據庫系統

數據庫系統的分層抽象DBMS 數據的三個層次從 數據 到 數據的結構----模式數據庫系統的三級模式&#xff08;三級視圖&#xff09;數據庫系統的兩層映像數據庫系統的兩個獨立性數據庫系統的標準結構 數據模型從 模式 到 模式的結構----數據模型三大經典數據模型 數據庫的演變與發…

【系統軟件03】centos7安裝和使用node-v18.16.0(centos7升級glibc 2.28)

【系統軟件03】centos7安裝和使用node-v18.16.0&#xff08;centos7升級glibc 2.28&#xff09; 前言&#xff1a;本文是解決node 18.16.0的依賴問題&#xff0c;具體的node安裝流程&#xff0c;可以參考我的另外一篇文章。一、下載node v18.16.0二、下載glibc2.28&#xff08;…

uniapp使用阿里矢量庫

然后解壓復制全部到你的項目文件 最后只要這幾個 然后引入 最后在你需要的頁面使用