堆排序(heapsort)是指利用堆這種資料結構所設計的一種排序演算法,它是一種選擇排序,時間複雜度是o(n log n),本部落格將使用最大堆來實現堆排序。對於堆的具體描述在本部落格的這篇文章(已經對最大堆這種資料結構做出了介紹,故不做重複介紹,主要介紹堆排序。以下是最大堆結構具體實現過程
import cn.zjut.util.sorttestutil;
//最大堆實現類
public class maxheap
//有參建構函式將傳入陣列作heapify操作將其轉化為堆
public maxheap(int arr, int n)
//獲取堆的尺寸大小
public int size()
//判斷堆是否為空
public boolean isempty()
//向堆中插入乙個元素
public void insert(int item)
//siftup操作
private void siftup(int k)
}//抽取最大值,對於最大堆就是抽取根結點元素
public int extractmax()
private void siftdown(int k) }}
堆排序的第一種實現方式,將陣列元素依次插入堆中,然後不斷抽取最大值從末尾開始往前賦值給原陣列,從而達到排序的目的。以下是這種方式的排序實現過程
public class heapsort
//抽取堆的最大值從原末尾賦值,符合公升序排序的特點
for(int i = n - 1; i >= 0; i--)
}以下是測試**
public class main
}以下是關於以上測試結果
從結果來看這種方式實現的堆排序針對隨機數組和近乎有序的陣列效果不錯 。堆排序還有另一種實現方式,在建立堆物件時利用建構函式傳入陣列進行heapify操作,然後就是如上一種方式一樣不斷抽取最大值元素從陣列末尾往前賦值從而達到排序要求,這種排序方式比上一種方式效率高,以下是這種方式實現過程
public class heapsortheapify }}
以下是針對兩種實現方式的測試**
import cn.zjut.util.sorttestutil;
public class main
}以下是相關測試結果
從結果上看,確實是第二種方式的時間效率比第一種方式的時間效率要好。還有一種堆排序叫原地堆排序,不需要建立額外陣列直接在原陣列上直接堆排序,而上述兩種實現方式都需要件堆空間複雜度需要額外的o(n)。思想是,其第乙個元素v就是根節點(最大值),在具體排序過程中最大值應在末尾位置w,將兩個值互換位置,此時最大值v在陣列末尾,那麼此時包含w在內(不包含末尾的v)的陣列部分就不是最大堆了,將w位置的值進行shift down操作,剩下部分再次成為「最大堆」,最大值仍在第乙個位置,那堆末尾的元素(即倒數第二個位置)與第乙個元素交換位置,再進行shift down操作,依次類推。以下是具體實現過程
import cn.zjut.util.sorttestutil;
public class heapsortinsitu
}private void siftdown(int arr, int n, int k) }}
針對以上三種實現方式進行測試,測試**如下
import cn.zjut.util.sorttestutil;
public class main
}以下是測試結果
從結果可知,原地堆排序與上述兩種方式實現的堆排序時間效率差不多,但其對空間複雜度有優化。以上整個過程就是堆排序的所有過程。
十大排序演算法之 堆排序 七)
堆排序 個人感覺算是十大排序演算法中較難的一種排序演算法。1 首先了解什麼是堆,需要滿足2個條件 滿足完全二叉樹 除了最後一層,每一層都是滿的,有右子樹的前提必需有左子樹 堆分為大頂堆和小頂堆,大頂堆 每乙個節點大於其左右子結點,小頂堆同理。2 完全二叉樹的特性 完全二叉樹適用於陣列儲存 對於乙個結...
十大排序 堆排序
堆排序屬於選擇排序 選擇排序的基本思想 每一趟 第i趟 在後面n i 1個待排序的元素中選取關鍵字最小的元素,作為有序子串行的第i個元素,直到第 n 1趟做完,待排序元素只剩下1個,就不用再選了。堆排序適合關鍵字較多的情況 n 1000 比如 在1億個數中選出前100個最大值?首先使用乙個大小為10...
十大排序演算法之堆排序,最優實現
堆排序是利用堆這種資料結構而設計的一種排序演算法,堆排序是一種選擇排序,它的最壞,最好,平均時間複雜度均為0 nlogn 它也是不穩定排序。堆是具有以下性質的完全二叉樹 將待排序序列構造成乙個大頂堆 此時,整個序列的最大值就是堆頂的根節點。將其與末尾元素進行交換,此時末尾就為最大值。然後將剩餘n 1...