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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

漫画:什么是堆排序

發布時間:2023/12/3 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 漫画:什么是堆排序 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉載自??漫畫:什么是堆排序

在上一篇漫畫中,小灰介紹了?二叉堆?這樣一種強大的數據結構:

漫畫:什么是二叉堆?(修正版)

那么,這個二叉堆怎樣來使用呢?我們這一期將會詳細講述。

?

?

讓我們回顧一下二叉堆和最大堆的特性:

1.二叉堆本質上是一種完全二叉樹

2.最大堆的堆頂是整個堆中的最大元素

當我們刪除一個最大堆的堆頂(并不是完全刪除,而是替換到最后面),經過自我調節,第二大的元素就會被交換上來,成為最大堆的新堆頂。

?

正如上圖所示,當我們刪除值為10的堆頂節點,經過調節,值為9的新節點就會頂替上來;當我們刪除值為9的堆頂節點,經過調節,值為8的新節點就會頂替上來.......

由于二叉堆的這個特性,我們每一次刪除舊堆頂,調整后的新堆頂都是大小僅次于舊堆頂的節點。那么我們只要反復刪除堆頂,反復調節二叉堆,所得到的集合就成為了一個有序集合,過程如下:

刪除節點9,節點8成為新堆頂:

?

刪除節點8,節點7成為新堆頂:

?

刪除節點7,節點6成為新堆頂:

刪除節點6,節點5成為新堆頂:

刪除節點5,節點4成為新堆頂:

?

刪除節點4,節點3成為新堆頂:

?

刪除節點3,節點2成為新堆頂:

?

到此為止,我們原本的最大堆已經變成了一個從小到大的有序集合。之前說過二叉堆實際存儲在數組當中,數組中的元素排列如下:

由此,我們可以歸納出堆排序算法的步驟:

1. 把無序數組構建成二叉堆。

2. 循環刪除堆頂元素,移到集合尾部,調節堆產生新的堆頂。

?

public class HeapSort { /** * 下沉調整 * @param array ? ? 待調整的堆 * @param parentIndex ? ?要下沉的父節點 * @param parentIndex ? ?堆的有效大小 */ 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 heapSort(int[] array) {// 1.把無序數組構建成二叉堆。for (int i = (array.length-2)/2; i >= 0; i--) {downAdjust(array, i, array.length);}System.out.println(Arrays.toString(array));// 2.循環刪除堆頂元素,移到集合尾部,調節堆產生新的堆頂。for (int i = array.length - 1; i > 0; i--) {// 最后一個元素和第一元素進行交換int temp = array[i];array[i] = array[0];array[0] = temp;// 下沉調整最大堆downAdjust(array, 0, i);} }public static void main(String[] args) {int[] arr = new int[] {1,3,2,6,5,7,8,9,10,0};heapSort(arr);System.out.println(Arrays.toString(arr)); } }

?

?

二叉堆的節點下沉調整(downAdjust 方法)是堆排序算法的基礎,這個調節操作本身的時間復雜度是多少呢?

?

假設二叉堆總共有n個元素,那么下沉調整的最壞時間復雜度就等同于二叉堆的高度,也就是O(logn)

我們再來回顧一下堆排序算法的步驟:

1. 把無序數組構建成二叉堆。

2. 循環刪除堆頂元素,移到集合尾部,調節堆產生新的堆頂。

第一步,把無序數組構建成二叉堆,需要進行n/2次循環。每次循環調用一次?downAdjust?方法,所以第一步的計算規模是??n/2 * logn,時間復雜度O(nlogn)

第二步,需要進行n-1次循環。每次循環調用一次?downAdjust?方法,所以第二步的計算規模是?(n-1) * logn ,時間復雜度?O(nlogn)

兩個步驟是并列關系,所以整體的時間復雜度同樣是?O(nlogn)

?

?

?

?

總結

以上是生活随笔為你收集整理的漫画:什么是堆排序的全部內容,希望文章能夠幫你解決所遇到的問題。

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