Java代碼為例講解堆的性質(zhì)和基本操作以及排序方法
堆的性質(zhì)
堆是一棵完全二叉樹,實際中可以通過一個數(shù)組來實現(xiàn),它最重要的一個性質(zhì)是:任意節(jié)點都小于(大于)等于其子節(jié)點。將根節(jié)點最小的堆稱為最小堆,根節(jié)點最大的堆稱為最大堆。下圖給出了一個最大堆的示例及其數(shù)組表示,可以直觀地看出每個節(jié)點都比它的孩子們都要大。
在上圖中可以看到,完全二叉樹的節(jié)點可以從根節(jié)點編號為1開始按順序排列,對應(yīng)數(shù)組A中的索引(注意此處下標(biāo)是從1開始的)。給定一個節(jié)點i,我們很容易可以得到它的左孩子是2i,右孩子是2i+1,父節(jié)點是i/2
堆的基本操作
堆有兩種基本操作(下面以最小堆為例):
插入元素k:直接將k添加到數(shù)組最后,然后向上冒泡(bubble-up)調(diào)整堆。向上冒泡操作:將要調(diào)整的元素與其父節(jié)點比較,如果大于其父節(jié)點則交換,直到恢復(fù)堆的性質(zhì)。
提取最值:最值即根元素。然后將其刪除,令根元素=最后的葉子結(jié)點元素,然后從根元素開始向下冒泡(bubble-down)調(diào)整堆。向下冒泡操作:每次應(yīng)該從要調(diào)整節(jié)點,其左右孩子一共三個節(jié)點中選擇最小的子節(jié)點來交換(如果最小就是其本身就不用交換),直到恢復(fù)堆的性質(zhì)。
實際中經(jīng)常需要將一個包含n個元素?zé)o序數(shù)組建立成堆,下面的Heap類中的構(gòu)造方法將展示如何通過_bubbleDown向下冒泡調(diào)整來建堆。堆實質(zhì)上是一棵完全二叉樹,樹高總為lognlogn,每種基本操作的耗時操作都在于冒泡調(diào)整以滿足堆的性質(zhì),因此它們的時間復(fù)雜度都是O(nlogn)O(nlogn)。
Java示例:
//上浮 public void swim(int k){ while(k/2>=1 && less(pq[k/2],pq[k])){ exch(pq,k/2,k); k=k/2; } } //下沉 private void sink() { int k=1; while(2*k<N){ int j=2*k; if(less(pq[j],pq[j+1])) j++; if(less(pq[k],pq[j])) exch(pq,k,j); else break; k = j; } }
堆排序?qū)崿F(xiàn)原理
分為兩步:
1.把數(shù)組排成二叉堆的順序
2.調(diào)換根節(jié)點和最后一個節(jié)點的位置,然后對根節(jié)點進行下沉操作。
實現(xiàn):
可能我的代碼和上面的動畫略有出入,不過基本原理差不多。
public class HeapSort extends BaseSort { private int N; @Override public void sort(Comparable[] a) { N =a.length-1; int k = N/2; while(k>=1){ sink(a,k); k--; } k = 1; while(k<=N){ exch(a,k,N--); sink(a,k); } } }
- java堆棧類使用實例(java中stack的使用方法)
- java內(nèi)存溢出示例(堆溢出、棧溢出)
- 輸出java進程的jstack信息示例分享 通過線程堆棧信息分析java線程
- Java編程思想里的泛型實現(xiàn)一個堆棧類 分享
- Java中堆和棧的區(qū)別詳解
- Java實現(xiàn)堆排序(Heapsort)實例代碼
- 深入JVM剖析Java的線程堆棧
- Java排序算法總結(jié)之堆排序
- java自帶的工具Jstack截取進程中的堆棧信息
- JAVA算法起步之堆排序?qū)嵗?/a>
- java中堆和棧的區(qū)別分析
- 基于Java堆內(nèi)存的10個要點的總結(jié)分析
- Java使用Deque實現(xiàn)堆棧的方法
- 詳解Java的堆內(nèi)存與棧內(nèi)存的存儲機制
相關(guān)文章
Java如何發(fā)起http請求的實現(xiàn)(GET/POST)
這篇文章主要介紹了Java如何發(fā)起http請求的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03Java深入了解數(shù)據(jù)結(jié)構(gòu)中常見的排序算法
這篇文章主要介紹了Java常用的排序算法及代碼實現(xiàn),在Java開發(fā)中,對排序的應(yīng)用需要熟練的掌握,這樣才能夠確保Java學(xué)習(xí)時候能夠有扎實的基礎(chǔ)能力。那Java有哪些排序算法呢?本文小編就來詳細(xì)說說Java常見的排序算法,需要的朋友可以參考一下2022-01-01java實現(xiàn)合并單元格的同時并導(dǎo)出excel示例
這篇文章主要給大家介紹了關(guān)于java實現(xiàn)合并單元格的同時并導(dǎo)出excel的相關(guān)資料,文中先進行了簡單的介紹,之后給出了詳細(xì)的示例代碼,相信對大家具有一定的參考價值,需要的朋友們下面來一起看看吧。2017-03-03Java流程控制之循環(huán)結(jié)構(gòu)for,增強for循環(huán)
這篇文章主要介紹了Java流程控制之循環(huán)結(jié)構(gòu)for,增強for循環(huán),for循環(huán)是編程語言中一種循環(huán)語句,而循環(huán)語句由循環(huán)體及循環(huán)的判定條件兩部分組成,其表達式為:for(單次表達式;條件表達式;末尾循環(huán)體){中間循環(huán)體;},下面我們倆看看文章內(nèi)容的詳細(xì)介紹2021-12-12java隊列實現(xiàn)方法(順序隊列,鏈?zhǔn)疥犃?循環(huán)隊列)
下面小編就為大家分享一篇java隊列實現(xiàn)方法(順序隊列,鏈?zhǔn)疥犃?循環(huán)隊列),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2017-12-12使用spring整合Quartz實現(xiàn)—定時器功能
這篇文章主要介紹了使用spring整合Quartz實現(xiàn)—定時器功能,不基于特定的基類的方法,需要的朋友可以參考下2018-04-04Windows系統(tǒng)編寫bat腳本啟動、停止及重啟Java服務(wù)jar包
在bat文件中我們將編寫一些代碼來運行Java jar文件,下面這篇文章主要給大家介紹了關(guān)于Windows系統(tǒng)編寫bat腳本啟動、停止及重啟Java服務(wù)jar包的相關(guān)資料,需要的朋友可以參考下2023-12-12