图解排序算法(三)之堆排序
堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种**选择排序,**它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序。
大顶堆:每个节点的值都大于其左右孩子节点的值。小顶堆:每个节点的值都小于其左右孩子节点的值。堆排序的基本思想是:将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了
步骤:
将无需序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆;将堆顶元素与末尾元素交换,将最大元素"沉"到数组末端;重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序。创建格式:
//升序队列,小顶堆 priority_queue <int,vector<int>,greater<int> > q; //降序队列,大顶堆,两种方式 priority_queue <int,vector<int>,less<int> >q; //priority_queue<int> q;//基本数据类型默认是大根堆 //greater和less是std实现的两个仿函数(就是使一个类的使用看上去像一个函数。其实现就是类中实现一个operator(),这个类就有了类似函数的行为,就是一个仿函数类了)示例:
/* * @Description: 使用priotity_queue实现大(小)根堆 * @Author: szq * @Github: https://github.com/MrQqqq * @Date: 2020-07-04 22:16:41 * @LastEditors: szq * @LastEditTime: 2020-07-04 22:32:38 * @FilePath: \cpp\src\priority_queue.cpp */ #include<vector> #include<queue> #include<iostream> using namespace std; int main(){ //创建大根堆的两种方式 //1.基本数据类型默认是大根堆 priority_queue<int> pq1; //2.标准格式 priority_queue<int,vector<int>,less<int>> pq2;//less是比较前一个元素和后一个元素的结果, //less小于的意思,因此整个队列是逆序的 //大根堆里添加元素 pq1.push(1); pq1.push(2); pq2.push(1); pq2.push(2); //测试大根堆顶部元素,大根堆顶部的元素为队列中最大的元素 cout << "大根堆pq1顶部元素为:" << pq1.top() << endl; cout << "大根堆pq2顶部元素为:" << pq2.top() << endl; //创建小根堆的方式 priority_queue<int,vector<int>,greater<int>> pq3;//greater是比较前一个元素和后一个元素的结果, //greater大于的意思,因此整个队列是顺序的 //向小根堆中添加元素 pq3.push(1); pq3.push(2); //测试小根堆顶部元素,小根堆顶部的元素为队列中最小的元素 cout <<"小根堆pq3顶部元素为:" << pq3.top() << endl; }自定义数据类型创建大根堆:
/* * @Description: 用自定义数据创建大根堆小根堆 * @Author: szq * @Github: https://github.com/MrQqqq * @Date: 2020-07-04 22:44:54 * @LastEditors: szq * @LastEditTime: 2020-07-04 22:49:51 * @FilePath: \cpp\src\priority_queue_mydata.cpp */ #include <iostream> #include <queue> using namespace std; //方法1 struct tmp1 //运算符重载< { int x; tmp1(int a) {x = a;} bool operator<(const tmp1& a) const { return x < a.x; //大顶堆 } }; //方法2 struct tmp2 //重写仿函数 { bool operator() (tmp1 a, tmp1 b) { return a.x < b.x; //大顶堆 } }; int main() { tmp1 a(1); tmp1 b(2); tmp1 c(3); priority_queue<tmp1> d; d.push(b); d.push(c); d.push(a); while (!d.empty()) { cout << d.top().x << '\n'; d.pop(); } cout << endl; priority_queue<tmp1, vector<tmp1>, tmp2> f; f.push(b); f.push(c); f.push(a); while (!f.empty()) { cout << f.top().x << '\n'; f.pop(); } }