lurenaa的博客

😘代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#pragma once
#include <iostream>
#include "Common.hpp"
#include <vector>
#include <algorithm>
using namespace std;
/**
* 堆排序
**/
template<typename T>
class HeapSort {
public:
static void sort(vector<T>&);
private:
static void sink(vector<T>& a, int k, int N);
};

template<typename T>
void HeapSort<T>::sort(vector<T>& a) {
int N = a.size() - 1;
for(int i = N / 2; i >= 1; --i)
sink(a, i, N);
while(N > 1) {
swap(a[1], a[N--]);
sink(a, 1, N);
}
}

template<typename T>
void HeapSort<T>::sink(vector<T>& a, int k, int N) {
int j;
while(k <= N / 2) {
j = 2 * k;
if(j < N && a[j] < a[j + 1]) ++j;
if(a[k] >= a[j]) break;
swap(a[k], a[j]);
k = j;
}
}

👿注意

  • 要注意父节点只有一个子节点时的情况,在sink函数中(if(j < N && a[j] < a[j + 1]) ++j;)一定要注意j<N,不能超出范围
  • 构造最大堆时,for循环从i = N / 2开始的原因是:sink中有限制条件while(k <= N / 2),所以N/2<i<N部分无法进入sink的while循环,是没有意义的,徒增N/2次比较
  • 递增排序使用最大堆,递减排序使用最小堆
  • vector的第一个值(下标为0)不使用