基本思想(默认升序):利用二叉树中的最大堆,每一个结点都比其所有子结点的值大的特点,第一个结点的值最大,将第一个结点与最后一个结点交换,这样最后一个结点肯定是最大的,然后对前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;
}
输出: