堆排序的的步骤(从小到大):
1. 先构建最大堆;
2. 维护一个tail,表示堆的底部,即数组中0-tail部分为堆,tail初始为nums.size()-1,tail之后的元素为已排好序的部分;
3. 将堆顶的元素与tail交换,tail减一,然后对堆顶的元素做一次down操作,重复这个步骤,直到tail为0;
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <random>
using namespace std;
void swap(vector<int>& nums, int i, int j)
{
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
void up(vector<int>& nums, int i)
{
int father = (i - 1) / 2;
if (i > 0 && nums[i] > nums[father])
{
swap(nums, i, father);
up(nums, father);
}
}
void down(vector<int>& nums, int i, int tail)
{
int son = i * 2 + 1;
if (son > tail)
return;
if (son + 1 <= tail && nums[son + 1] > nums[son])
++son;
if (nums[i] < nums[son])
{
swap(nums, i, son);
down(nums, son, tail);
}
}
void heapSort(vector<int>& nums, int tail)
{
for (int i = 0; i < nums.size(); ++i)
up(nums, i);
for (int i = nums.size() - 1; i > 0; --i)
{
swap(nums, 0, i);
down(nums, 0, i - 1);
}
}
int main()
{
default_random_engine e;
uniform_int_distribution<int> u(0, 1000);
vector<int> nums(0);
for (int i = 0; i < 20; ++i)
nums.push_back(u(e));
for (int i = 0; i < nums.size(); ++i)
cout << nums[i] << " ";
cout << endl;
heapSort(nums, nums.size() - 1);
for (int i = 0; i < nums.size(); ++i)
cout << nums[i] << " ";
cout << endl;
return 0;
}