01 思路
以从小到大排列为例。
代码用到以下几个模块
- swap模块
- 完成一个数组中的两个位置的元素交换
- heapify模块
- 完成将一个子树构建为根节点最大的形式。
- 如果根节点不是最大值,那么交换后将对传入最大位置的序号进行递归。
- build_heap模块
- 从倒数第二层开始反向依次调用heepify模块,直到0节点。
- sort模块
- 首先调用build_heap建堆,再从最后一个位置依次与0位置交换,并且每次交换后对0位置进行heapify。
02 Show me the code
#include <iostream>
using namespace std;
// 堆排序======================================================
void swap(float ar[], const int dex_a, const int dex_b) {
if (dex_a == dex_b) {
return;
}
float temp = ar[dex_a];
ar[dex_a] = ar[dex_b];
ar[dex_b] = temp;
}
void heapify(float ar[], const int len, const int dex_of_now) {
// 计算其左孩子、右孩子的序号
const int left_c = 2 * dex_of_now + 1;
const int right_c = 2 * dex_of_now + 2;
if (dex_of_now >= len) {
return;
}
int max = dex_of_now;
if (left_c < len && ar[left_c] > ar[max]) {
max = left_c;
}
if (right_c < len && ar[right_c] > ar[max]) {
max = right_c;
}
if (max != dex_of_now) {
swap(ar, max, dex_of_now);
heapify(ar, len, max);
}
}
void build_heap(float ar[], const int len) {
int i = 0;
for (i = (len - 2) / 2; i >= 0; --i) {
heapify(ar, len, i);
}
}
void sort(float origin[], const int size) {
// 建堆
build_heap(origin, size);
// 倒序遍历调换
int i = 0;
for (i = size - 1; i >= 0; --i) {
swap(origin, 0, i);
// 交换后0节点heapify
heapify(origin, i, 0);
}
}
// =======================================================
void show(float ar[], const int LEN) {
for (int i = 0; i < LEN; ++i) {
cout << ar[i] << " ";
}
cout << endl;
}
int main() {
const int N = 15;
float* origin = new float[N];
for (int i = 0; i < N; ++i) {
origin[i] = rand() % 100;
}
cout << "原始数组:" << endl;
show(origin, N);
cout << endl;
// 排序
sort(origin, N);
cout << "堆排序后:" << endl;
show(origin, N);
return 0;
}
03 结果
原始数组:
7 49 73 58 30 72 44 78 23 9 40 65 92 42 87
堆排序后:
7 9 23 30 40 42 44 49 58 65 72 73 78 87 92