參考文獻
堆排序思想
Step 1: 構造初始堆
初始化堆時是對所有的非葉子結點進行篩選;
最後一個非終端元素的下標是[n/2]向下取整,所以篩選只需要從第[n/2]向下取整個元素開始,從後往前進行調整。
Step 2:進行堆排序
堆排序是一種選擇排序。建立的初始堆爲初始的無序區。
排序開始,首先輸出堆頂元素(因爲它是最值),將堆頂元素和最後一個元素交換,這樣,第n個位置(即最後一個位置)作爲有序區,前n-1個位置仍是無序區,對無序區進行調整,得到堆之後,再交換堆頂和最後一個元素,這樣有序區長度變爲2。
不斷進行此操作,將剩下的元素重新調整爲堆,然後輸出堆頂元素到有序區。每次交換都導致無序區-1,有序區+1。不斷重複此過程直到有序區長度增長爲n-1,排序完成。
時間複雜度:O(nlogn)
手寫堆排序
void HeapCore(vector<int> &vec ,int size, int end)
{
int i = end;
int j = i;
bool flag = false;
do{
flag = false;
if(i * 2 < size && vec[i] > vec[i *2])
j = i*2;
if(i *2 + 1 < size && vec[i*2 + 1] < vec[i*2] && vec[i] > vec[i *2] )
j = i*2 + 1;
if(i != j)
{
int tmp = vec[j];
vec[j] = vec[i];
vec[i] = tmp;
flag = true;
}
i = j;
}while(flag && i < size);
}
void Heap(vector<int >&vec)
{
for(int i = (vec.size() - 1)/2 ; i > 0 ; i--)
HeapCore(vec , vec.size() ,i);
for(int i = vec.size() - 1; i > 0 ; i--) // 將第一個個與最後一個交換
{
int tmp = vec[1];
vec[1] = vec[i];
vec[i] = tmp;
if(i > 1)
HeapCore(vec , i , 1);
}
}
int main()
{
vector<int > vec;
for(int i = 0 ; i < 100 ; i++)
vec.push_back(i);
Heap(vec);
}