偶然遇到了一个可用堆排序解决的问题,查了一下,STL库中自带简单的堆排序。
直接上代码:
#include "stdafx.h"
#include
#include
#include
using namespace std;
void print_vec(const vector& vec) {
for (auto i : vec)
{
cout << i << " ";
}
cout << endl;
}
int main()
{
vector vec{5,3,8,6,2,7,1,4,9};
make_heap(vec.begin(),vec.end());
cout << "构造大根堆:" << endl;
print_vec(vec);
cout << "插入:" << endl;
vec.push_back(10);
push_heap(vec.begin(), vec.end());
print_vec(vec);
cout << "删除: " << endl;
pop_heap(vec.begin(),vec.end());
print_vec(vec);
//pop_heap只是把堆顶元素放到了容器最后面,
//还需要手动删除
cout << "手动删除后:" << endl;
vec.pop_back();
print_vec(vec);
return 0;
}
结果:
构造大根堆:
9 6 8 5 2 7 1 4 3
插入:
10 9 8 5 6 7 1 4 3 2
删除:
9 6 8 5 2 7 1 4 3 10
手动删除后:
9 6 8 5 2 7 1 4 3
注意:1.需要引入algorithm头文件,2.默认是大根堆排序。
-----------------------------------------------------------------分割线-------------------------------------------------------------------------------
关于push_heap: 看代码,我先往vec中添加了一个元素10,再对vec进行排序。百度上查的push_heap就是对插入到容器尾部的元素做一次调整。原理就是数据结构书上写得貌似叫向上调整之类的,不停比较vec[i]和vec[i/2]大小做交换,手动模拟一次就明白了。
关于pop_heap:把堆顶元素放到容器末尾,再对其他元素进行调整。原理是先将原队尾的元素放到堆顶,再向下调整,方法同上。最后记得手动删除掉末尾的元素。
-----------------------------------------------------------------分割线-------------------------------------------------------------------------------
再来看一下如何做小根堆:
int main()
{
vector vec{5,3,8,6,2,7,1,4,9};
make_heap(vec.begin(),vec.end(),greater());
cout << "greater构造小根堆:" << endl;
print_vec(vec);
cout << "插入:" << endl;
vec.push_back(10);
push_heap(vec.begin(),vec.end());
print_vec(vec);
return 0;
}
结果:
(此处应该有一个一脸懵逼的表情包)
好吧,push_heap不添加比较函数则默认使用大根堆调整,且注意,push_heap和pop_heap使用前,应该保证容器中的序列是堆排序的,这两个函数只负责将添加的元素调整和删除堆顶元素,不管其他事情。
还有自定义排序方式,这次没用上,不想记录了,就是写一个结构体/类,对大于号>和小于号<重载,返回bool值,给到参数里就行了。
希望疫情能赶快过去。
告辞!