排序演算法之堆排序

2021-08-20 14:56:26 字數 2080 閱讀 4504

堆排序(heapsort)是指利用堆這種資料結構所設計的一種排序演算法。堆積是乙個近似完全二叉樹的結構,並同時滿足堆積的性質:即子結點的鍵值或索引總是小於(或者大於)它的父節點。

1、演算法描述

1. 將初始待排序關鍵字序列(r1,r2….rn)構建成最大堆,此堆為初始的無序區;

2. 將堆頂元素r[1]與最後乙個元素r[n]交換,此時得到新的無序區(r1,r2,……rn-1)和新的有序區(rn),且滿足r[1,2…n-1]<=r[n];

3. 由於交換後新的堆頂r[1]可能違反堆的性質,因此需要對當前無序區(r1,r2,……rn-1)調整為新堆,然後再次將r[1]與無序區最後乙個元素交換,得到新的無序區(r1,r2….rn-2)和新的有序區(rn-1,rn)。不斷重複此過程直到有序區的元素個數為n-1,則整個排序過程完成。

2、演算法**

(1)最大堆與最小堆

(2)構建最大堆

(3)堆排序

3、演算法demo

#include 

using

namespace

std;

//建立堆積樹(從下往上調整)

void create_heap(vector

&a, int i, int heapsize)

}//堆排序

void heap_sort(vector

&a)// 將堆頂元素與末尾元素進行交換,使末尾元素最大。然後繼續調整堆,

// 再將堆頂元素與末尾元素交換,得到第二大元素。如此反覆進行交換、重建、交換。

for(int i = length - 1; i >= 0; --i)

}int main(int argc, char

const *argv)

; heap_sort(vec1);

for (const

auto v : vec1)

cout

<< v << " ";

cout

<< endl;

vector

vec2 = vec1;

//stl中的建堆和堆排序

make_heap(vec2.begin(), vec2.end());

sort_heap(vec2.begin(), vec2.end());

for (const

auto v : vec2)

cout

<< v << " ";

cout

<< endl;

system("pause");

return

0;}

4、演算法總結堆排序是一種不穩定排序,整體主要由構建初始堆+交換堆頂元素和末尾元素並重建堆兩部分組成。其中構建初始堆經推導複雜度為o(n),在交換並重建堆的過程中,需交換n-1次,而重建堆的過程中,根據完全二叉樹的性質,[log2(n-1),log2(n-2)…1]逐步遞減,近似為nlogn。所以堆排序時間複雜度一般認為就是o(nlogn)。

簡單總結下堆排序的基本思路:

1. 將無需序列構建成乙個堆,根據公升序降序需求選擇最大堆或最小堆;

2. 將堆頂元素與末尾元素交換,將最大元素」沉」到陣列末端;

3. 重新調整結構,使其滿足堆定義,然後繼續交換堆頂元素與當前末尾元素,反覆執行調整+交換步驟,直到整個序列有序。

參考:

排序演算法之堆排序

前言 今天我來介紹下堆排序,在寫堆排序 之前,我們要知道堆的概念!堆的定義 n個關鍵字序列kl,k2,kn稱為 heap 當且僅當該序列滿足如下性質 簡稱為堆性質 1 ki k 2i 且ki k 2i 1 1 i n 當然,這是小根堆,大根堆則換成 號。k i 相當於二叉樹的非葉子結點,k 2i 則...

排序演算法之堆排序

堆排序演算法是選擇排序的一種,該演算法只是通過堆,最大堆 或者最小堆選擇出乙個待排序序列中的最大值,或者最小值。要想實現堆排序演算法,就需要構建什麼堆,這裡也最小堆為例。說明什麼是堆,怎麼構建乙個堆。假設待排序序列為a n 為乙個陣列。陣列的長度為n 陣列下標為 0,1,2,i,2i,2i 1 n ...

排序演算法之堆排序

宣告 本博文 為樓主親自編寫並測試,其它內容引用至我一直很崇拜的牛人morewindows。他對排序演算法的講解通俗易懂,給人一種耳目一新的感覺。堆排序與快速排序 歸併排序 一樣都是時間複雜度為o n logn 的幾種常見排序方法。最小堆的講解以及最小堆元素的插入和刪除參見最小堆操作。以下繼續引用以...