排序演算法 堆排序

2021-10-04 02:34:25 字數 2212 閱讀 7407

堆排序是利用堆這種資料結構而設計的一種排序演算法,堆排序是一種選擇排序,它的最壞,最好,平均時間複雜度均為o(nlogn),它也是不穩定排序。首先簡單了解下堆結構。

堆(heap)是電腦科學中一類特殊的資料結構的統稱。堆通常是乙個可以被看做一棵完全二叉樹的陣列:每個結點的值都大於或等於其左右孩子結點的值,稱為大頂堆;或者每個結點的值都小於或等於其左右孩子結點的值,稱為小頂堆。如下圖:

同時,我們對堆中的結點按層進行編號,將這種邏輯結構對映到陣列中就是下面這個樣子

該陣列從邏輯上講就是乙個堆結構,我們用簡單的公式來描述一下堆的定義就是:

堆排序的基本思想是:將待排序序列構造成乙個大頂堆,此時,整個序列的最大值就是堆頂的根節點。將其與末尾元素進行交換,此時末尾就為最大值。然後將剩餘n-1個元素重新構造成乙個堆,這樣會得到n個元素的次小值。如此反覆執行,便能得到乙個有序序列了。

將給定無序序列構造成乙個大頂堆(一般公升序採用大頂堆,降序採用小頂堆)。

將堆頂元素與末尾元素進行交換,使末尾元素最大。

然後繼續調整堆,再將堆頂元素與末尾元素交換,得到第二大元素。如此反覆進行交換、重建、交換。

/*

堆排序的基本思路:

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

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

c.重新調整結構,使其滿足堆定義,然後繼續交換堆頂元素與當前末尾元素,

反覆執行調整+交換步驟,直到整個序列有序。

*/#include

void

adjustheap

(int

*data,

int i,

int length)

if(data[k]

>temp)

else

} data[i]

= temp;

//將temp值放到最終的位置

}void

heap_sort

(int data,

int n)

//2.調整堆結構+交換堆頂元素與末尾元素

for(i=n-

1; i>=

1; i--)}

intmain()

;printf

("排序前的資料為:\n");

for(

int i=

0; i<

10;i++

)printf

("%d "

,data[i]);

printf

("\n\n");

heap_sort

(data,10)

;printf

("排序後的結果為:\n");

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

排序方法

時間複雜度(平均)

時間複雜度(最壞)

時間複雜度(最好)

空間複雜度

穩定性堆排序

o(nlog2n)

o(nlog2n)

o(nlog2n)

o(1)

不穩定

排序演算法 堆排序

1 什麼是堆 首先它是一顆完全二叉樹,並且父結點的值大於子節點的值 最大堆 或父結點的值小於子結點的值 最小堆 小根堆 根結點 亦稱為堆頂 的關鍵字是堆裡所有結點關鍵字中最小者的堆稱為小根堆,又稱最小堆。大根堆 根結點 亦稱為堆頂 的關鍵字是堆裡所有結點關鍵字中最大者,稱為大根堆,又稱最大堆。2 堆...

排序演算法 堆排序

花了一晚上時間研究堆排序,這個排序困擾了哥很久,終於搞清楚了。一 堆的定義 1.父結點的鍵值總是大於或等於 小於或等於 任何乙個子節點的鍵值 2 每個結點的左子樹和右子樹都是乙個二叉堆 都是最大堆或最小堆 二 已知結點 i 則它的子結點 為2 i 1 與 2 i 2 父節點為 i 1 2 三 堆排序...

排序演算法 堆排序

由於不經常使用,之前學習看過的演算法都給忘了。現在把他們寫下來,記錄下來,以方便以後查閱。本篇文章的 即為堆排序的 主函式中是對輸入檔案中的序列進行排序,並將結果輸出到乙個檔案中。這是一種形式類似於google codejam的測試方法。include include using namespace...