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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

排序算法 | 堆排序,算法的图解、实现、复杂度和稳定性分析

發布時間:2025/3/20 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 排序算法 | 堆排序,算法的图解、实现、复杂度和稳定性分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
  • 今天講解一下堆排序的原理以及實現、復雜度和穩定性分析


目錄

    • 1 堆的定義
    • 2 堆排序的思路
    • 3 代碼實現
    • 4 堆的輸出(刪除操作)
    • 5 堆的插入操作
    • 6 堆排序的特點
    • 7 性能分析

1 堆的定義

堆排序(英語:Heapsort)是指利用堆這種數據結構所設計的一種排序算法。堆是一個近似完全二叉樹的結構,并同時滿足堆積的性質:即子結點的鍵值或索引總是小于(或者大于)它的父節點。

定義:
n個關鍵字序列L[1…n]稱為堆,當且僅當該序列滿足:

① L(i)>=L(2i) 且 L(i)>=L(2i+1)或

② L(i)<=L(2i) 且 L(i)<=L(2i+1) (1≤isln/2])

可以將該一維數組視為一棵完全二叉樹

大根堆:滿足條件① 的堆稱為大根堆(大頂堆),大根堆的最大元素存放在結點,且其任一非根結點的值小于等于其雙親結點值

對于堆中的元素編號,其實也是邏輯結構映射到數組的一個過程;

小根堆:滿足條件2的堆稱為小根堆(小頂堆),小根堆的定義剛好相反,結點是最小元素

2 堆排序的思路

首先將存放在L[1…n]中的n個元素建成初始堆,由于堆本身的特點(以大頂堆為例),堆頂元素就是最大值。
輸出堆頂元素后,通常將堆底元素送入堆頂,堆被破壞,將堆頂元素向下調整使其繼續保持大頂堆的性質,再輸出堆頂元素。如此重復。

  • 根據數組構建一個完全二叉樹
  • 從最后一個非葉節點開始調整,使得子樹成為堆
  • 如此重復,直至滿足堆的定義

值得注意的是:

大根堆排序結果為升序

小根堆排序結果為降序

這是一個常見的誤區!

這是因為:堆使用的時候都是每次把堆頂的元素干掉留下堆內部的元素做成Top N

如果你要找100000中的 TOP100最大的,你用小根堆

如果你要找100000中的 TOP100最小的,你用大根堆

3 代碼實現

void BuildMaxHeap(int *arr,int len) {// 建立初始大根堆 for(int i = (len-1)/2; i >= 0; i--){HeapAdjust(arr,i,len);} }// 子樹調整 void HeapAdjust(int *arr,int k,int len) {int temp = arr[k]; // 暫存根節點 for(int i = k*2+1;i < len;i = i*2+1){if (i < len-1 && arr[i] < arr[i+1])i++;if (temp >= arr[i])break; // 篩選結束 else {arr[k] = arr[i];k = i; // 繼續向下篩選 }}arr[k] = temp ; // 篩選的值放入最終位置 }void HeapSort(int *arr,int len) {BuildMaxHeap(arr,len);for(int i = len-1;i > 0;i--){ arr[0] = arr[0] ^ arr[i]; arr[i] = arr[0] ^ arr[i]; arr[0] = arr[0] ^ arr[i];HeapAdjust(arr,0,i);} }

4 堆的輸出(刪除操作)

堆中根結點的值肯定是最值,不是最大就是最小,往往需要使用到。

即每次都刪除第0個數據(根結點)

那么堆中輸出根節點之后如何保證堆原有的特性呢?

刪除之后,打破了原有規律,需要調整!

  • 刪除根結點

  • 最后一個數據的值賦給根結點

  • 然后再從根結點開始進行一次從上向下的調整


5 堆的插入操作

  • 對堆進行插入操作時,先將新結點放在堆的末端

  • 隨后再向上執行調整操作



6 堆排序的特點

堆排序適合關鍵字較多的情況(如n>1000)
不適合關鍵字較少的情況
大根堆排序結果為升序
小根堆排序結果為降序

例如,在1千萬個數中選出前100個最大值?
首先使用一個大小為100的數組,讀入前100個數,建立小頂堆,而后依次讀入余下的數,若小于堆頂則舍棄,否則用該數取代堆頂并重新調整堆,待數據讀取完畢,堆中100個數即為所求。

7 性能分析

【空間復雜度】:僅使用常數個輔助單元,空間復雜度為 O(1)

【時間復雜度】:建堆時間為 O(n),之后有n-1次向下調整操作,每次調整的時間復雜度為 O(h) h表示樹高

故在最好、最壞和平均情況下,堆排序的時間復雜度為 O(nlog2n)

【穩定性】:進行篩選時,有可能把后面相同關鍵字的元素調整到前面,所以堆排序算法是一種不穩定的排序方法

總結

以上是生活随笔為你收集整理的排序算法 | 堆排序,算法的图解、实现、复杂度和稳定性分析的全部內容,希望文章能夠幫你解決所遇到的問題。

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