1.思路【以大根堆为例】:
- 假定左子树和右子树都为大根堆,调整根节点、左子树、右子树,使整棵树为大根堆【heapify函数作用】
- 建堆:从最后一个非叶子节点,循环调用heapify函数建立大根堆
- 将根节点【序号为0位置】和最后一个元素位置【序号为n】交换,再将序号0到n-1元素heapfiy建立大根堆
- 循环调用第三点的步骤,排序完毕。
2.代码
// heap_sort.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include "pch.h"
#include <iostream>
#include <vector>
using namespace std;
void swap(vector<int>& arr, int i, int j)
{
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
void heapify(vector<int>&arr, int parent_idx, int n) //父节点parent_idx, 对前n个值堆化
{
int j = 2 * parent_idx + 1; //子孩子中较大的下标
int temp = arr[parent_idx];
while (j < n)
{
if (j + 1 < n && arr[j] < arr[j + 1])
{
j++;
}
if (arr[j] > temp)
{
arr[parent_idx] = arr[j];
//swap(arr, j, parent_idx);
}
else//父节点就是最大值,直接退出
{
break;
}
parent_idx = j;
j = 2 * parent_idx + 1;
}
arr[parent_idx] = temp;
}
int main()
{
vector<int>arr = { 9,8,7,6,5,4,3,2,1 };
for (int i = arr.size() / 2 - 1; i >= 0; i--)
{
heapify(arr, i, arr.size());
}
for (int i = arr.size() - 1; i > 0; i--)
{
swap(arr, i, 0);
heapify(arr, 0, i);
}
return 0;
}
注意:heapify中先比较子孩子中较大值的下标,再将较大值和父节点值做比较。
3.priority_queue 实现堆排序
- 头文件 #include<queue>
- 函数说明:priority_queue<Type, Container, Functional> Type:数据类型 Container:保存数据的容器 Functional:元素的比较方式
- priority_queue<int>p:默认容器用vector,比较方式operator<,原先队列是大顶堆
- priority_queue<int, vector<int>, greater<int> >p:小顶堆
- 自定义比较方式
在类外先定义比较方式:
struct compare
{
bool operator() (const pair<string, int> &val1, const pair<string, int> &val2)
{
….
}
}
在类内使用自定义比较方法
priority_queue<pair<string, int>, vector<pari<string, int> >, compare> pq;