原地堆排序

2021-08-02 06:19:02 字數 3143 閱讀 5529

--------------------siwuxie095

原地堆排序

程式 1:原地堆排序的實現

sorttesthelper.h:

#ifndef sorttesthelper_h

#define sorttesthelper_h

#include

#include

#include

#include

#include

using namespacestd;

//輔助排序測試

namespacesorttesthelper

returnarr;}//

生成乙個近乎有序的陣列

int*generatenearlyorderedarray(intn, intswaptimes)

//以當前時間為隨機種子

srand(time(null));

//再隨機挑選幾對元素進行交換,就是乙個近乎有序的陣列了

for(inti = 0; i < swaptimes; i++)

returnarr;

}template

voidprintarray(t arr, intn)

cout << endl;}//

經過排序演算法排序後,再次確認是否已經完全排序

template

boolissorted(t arr, intn)

}return true;}//

衡量乙個演算法的效能如何,最簡單的方式就是看這個演算法在特定資料集上的執行時間//(

1)傳入排序演算法的名字,方便列印輸出

//(2)傳入排序演算法本身,即函式指標

//(3)傳入測試用例:陣列和元素個數

template

voidtestsort(string sortname, void(*sort)(t, int), t arr, intn)

//複製陣列

int*copyintarray(inta, intn)

//判斷兩個陣列是否相同

boolaresameintarrs(int* arr, int* arr2, intn)

}return true;}}

#endif

heapsort.h:

#ifndef heapsort_h

#define heapsort_h

template

void__shiftdown(t arr, intn, intk)

if(arr[k] >= arr[j])

swap(arr[k], arr[j]);

k = j;}}

//原地堆排序:從小到大進行排序(最大堆)

template

voidheapsort(t arr, intn) //

倒序的從最後乙個元素開始,進行

swap

操作//

和shift down

操作,完成堆排序

for(inti = n - 1; i > 0; i--)}//

原地堆排序主要使用了

heapify

演算法和shift down

演算法//

//關於索引(從

0開始)://(

1)parent(i) = (i-1) / 2//(

2)left child(i) = 2 * i + 1//(

3)right child(i) = 2 * i + 2

////

另://

最後乙個非葉子節點的索引

=(count - 2) / 2

或count/2 - 1

////

注意://(1

)若要從小到大進行原地排序,只能使用最大堆//(

2)若要從大到小進行原地排序,只能使用最小堆

#endif

main.cpp:

#include"sorttesthelper.h"

#include"heapsort.h"

intmain()

執行一覽:

程式 2:原地堆排序的優化(在程式 1 的基礎上,修改 heapsort.h 即可)

heapsort.h:

#ifndef heapsort_h

#define heapsort_h

//使用插入排序的優化方式進行優化

template

void__shiftdown(t arr, intn, intk)

if(e >= arr[j])

arr[k] = arr[j];

k = j;

}arr[k] = e;}//

原地堆排序:從小到大進行排序(最大堆)

template

voidheapsort(t arr, intn) //

倒序的從最後乙個元素開始,進行

swap

操作//

和shift down

操作,完成堆排序

for(inti = n - 1; i > 0; i--)}//

原地堆排序主要使用了

heapify

演算法和shift down

演算法//

//關於索引(從

0開始)://(

1)parent(i) = (i-1) / 2//(

2)left child(i) = 2 * i + 1//(

3)right child(i) = 2 * i + 2

////

另://

最後乙個非葉子節點的索引

=(count - 2) / 2

或count/2 - 1

////

注意://(1

)若要從小到大進行原地排序,只能使用最大堆//(

2)若要從大到小進行原地排序,只能使用最小堆

#endif

執行一覽:

原地堆排序

上一節講的兩種堆排序都需要開闢o n 的輔助空間 建構函式中使用new分配的輔助空間 程式在開闢輔助空間和釋放空間的時候也會消耗一定的時間,若能多陣列進行原地堆排序,則省去了開闢和釋放空間的時間,時間效能會好一些。給定乙個大小為n的陣列,將這個陣列heapify,變為最大堆,此時陣列的第乙個元素就是...

原地堆排序

堆排序 我之前使用的堆排序是要開 乙個長度為 n的陣列,事實上,我們可以把原陣列看成乙個堆,也就是說我們不用開乙個陣列,而是在原地排序 怎麼說呢 還是給我乙個陣列,我對這個陣列進行heapify 操作,這樣就得到了乙個大根堆 腦袋是最大的 然後我們把最大的那個數和陣列的最後乙個元素交換,這樣一來,陣...

實現原地堆排序(CPP)

堆是一種非常有用的資料結構,我們可以利用大頂堆或者小頂堆這種資料結構完成堆排序,但是這樣會增加o n 的輔助空間,其實,真正的堆排序是可以在原地進行的,我們稱之為原地堆排序,今天我們就來實現一下原地堆排序吧。原地堆排序主要分兩個步驟 1.對陣列進行堆化 2.將最大元素與陣列末端元素交換,然後對前n ...