基本思想(默認升序):利用二叉樹中的最大堆,每一個結點都比其所有子結點的值大的特點,第一個結點的值最大,將第一個結點與最後一個結點交換,這樣最後一個結點肯定是最大的,然後對前n-1個元素 重新進行構造最大堆,再重複上述步驟;
平均時間複雜度: O(N log N);
demo:
#include<iostream>
#include<vector>
using namespace std;
//堆排序 時間複雜度 O(n* log n)
/*
藉由二叉樹的最大堆(最小堆)實現,對於升序,先將數組 排成 最大堆,降序則派成最小堆;
然後, 每次將二叉樹第一個元素與最後一個元素交換,這樣最後一個元素就是最大(最小)值,
然後重新將前面N-1個元素構建成最大堆;
重複操作,將第一個元素與倒數第N個元素交換,在將前N-1個元素 構建成最大堆;
*/
#define RADIX 10
void my_swap(int& first, int& second)
{
int tmp = first;
first = second;
second = tmp;
}
//構建堆
void BuildHeap(vector<int>&vec, int index, int last)
{
int parent, child;
int val = vec[index];//處理的元素
for (parent = index; parent*2+1 <= last; parent = child)
{
child = parent * 2 + 1;
//child指向左右結點中的較大者
if (child < last && vec[child] < vec[child + 1])
child++;
if (val >= vec[child]) break; //找到位置
else vec[parent] = vec[child];//繼續向下
}
vec[parent] = val;
}
void HeapSort(vector<int>&vec)
{
if (vec.size()<2) return;
int last = vec.size()-1;
//從最後一個結點的父節點開始,構建最大堆,根結點是 index=0
for (int i = (last-1 )/2; i >= 0; i--)
{
BuildHeap(vec, i, last);
/*cout << "heap:" << endl;
for (int j=i; j <=last; j++)
cout << vec[j] << " ";
cout << endl;*/
}
while (last >= 0)
{
my_swap(vec[0], vec[last--]);
BuildHeap(vec, 0, last);
}
}
int main()
{
vector<int> arr = { 12,5,9,34,3,97,63,23,53,87,120,999,1024,11,77 };
//vector<int> arr = { 12,5,9,34 };
cout << "raw val is:\n";
for (auto i : arr)
cout << i << "\t";
cout << endl;
HeapSort(arr);
cout << "HeapSort val is:\n";
for (auto i : arr)
cout << i << "\t";
cout << endl;
system("pause");
return 0;
}
輸出: