重点是堆排序怎么实现。
我的写法:
#include <iostream>
#include <vector>
// 辅助函数:调整堆
void heapify(std::vector<int>& arr, int n, int i) {
int largest = i; // 初始化最大值为根节点
int left = 2 * i + 1; // 左子节点
int right = 2 * i + 2; // 右子节点
// 如果左子节点大于根节点
if (left < n && arr[left] > arr[largest])
largest = left;
// 如果右子节点大于当前最大值
if (right < n && arr[right] > arr[largest])
largest = right;
// 如果最大值不是根节点
if (largest != i) {
std::swap(arr[i], arr[largest]);
// 递归地调整受影响的子树
heapify(arr, n, largest);
}
}
// 主函数:堆排序
void heapSort(std::vector<int>& arr) {
int n = arr.size();
// 从最后一个非叶子节点开始构建最大堆
for (int i = n / 2 - 1; i >= 0; i--)
heapify(arr, n, i);
// 一个个地从堆中取出元素
for (int i = n - 1; i > 0; i--) {
// 将当前根节点与末尾节点交换
std::swap(arr[0], arr[i]);
// 调整堆
heapify(arr, i, 0);
}
}
// 测试函数
int main() {
std::vector<int> arr = {3,1, 2, 8, 7, 5 ,9 ,4 ,6 ,0};
heapSort(arr);
std::cout << "Sorted array is \n";
for (int i : arr)
std::cout << i << " ";
std::cout << std::endl;
return 0;
}
柳神写法,非递归:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
void downAdjust(vector<int> &b, int low, int high) {
int i = 1, j = i * 2;
while(j <= high) {
if(j + 1 <= high && b[j] < b[j + 1]) j = j + 1;
if (b[i] >= b[j]) break;
swap(b[i], b[j]);
i = j; j = i * 2;
}
}
int main() {
int n, p = 2;
scanf("%d", &n);
vector<int> a(n + 1), b(n + 1);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
for(int i = 1; i <= n; i++) scanf("%d", &b[i]);
while(p <= n && b[p - 1] <= b[p]) p++;
int index = p;
while(p <= n && a[p] == b[p]) p++;
if(p == n + 1) {
printf("Insertion Sort\n");
sort(b.begin() + 1, b.begin() + index + 1);
} else {
printf("Heap Sort\n");
p = n;
while(p > 2 && b[p] >= b[1]) p--;
swap(b[1], b[p]);
downAdjust(b, 1, p - 1);
}
printf("%d", b[1]);
for(int i = 2; i <= n; i++)
printf(" %d", b[i]);
return 0;
}