前言
害怕面试官不允许使用库,一怒之下手撕该题代码,手撕堆排(heapSort),make_heap/pop_heap/push_heap函数;另外因为要实现堆排,涉及到了类内成员变量作引用传参的知识点,这个应该面试也会问;下面上代码和问题
遇到的问题总结:
1. 类内没有实例化模板类,报错C2440,“初始化”: 无法从“initializer list”转换为,必须实例化模板类。
2. 类内成员变量作引用,必须声明 为引用变量,同时采用有参构造的初始化形式进行初始化。否则无法对外部变量进行更改;直接赋值,报错您没有初始化。
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
struct myless { bool operator ()(int a, int b) { return a < b; } };
struct mygreater { bool operator ()(int a, int b) { return a > b; } };
template<class a>
class Heap {
public:
a cmp;//实例化模板类,不然报错C2440
vector<int> & heap; //必须声明为引用变量,不然无法对外部变量进行更改。
Heap() {};//无参构造
Heap(vector<int> &vt) :heap(vt) {
//heap = vt;//赋值报错,必须使用初始化形式 :heap(vt)
};//有参构造
void heapSort() {//O(nlogn)
heapBuild();
for (int i = heap.size() - 1; i > 0; i--) {
swap(heap[0], heap[i]);
heapAdjust(heap, 0, i - 1);
}
}
void heapBuild() {//O(logn)
for (int i = (heap.size() - 2) / 2; i >= 0; i--) {
heapAdjust(heap, i, heap.size() - 1);
}
}
void heapAdjust(vector<int> &heap, int s, int m) {
int temp, j;
temp = heap[s];
for (j = 2 * s + 1; j <= m; j = j * 2 + 1) {
if (j < m && cmp(heap[j], heap[j + 1])) j++;
if (!cmp(temp, heap[j])) break;
heap[s] = heap[j];
s = j;
}
heap[s] = temp;
}
void popHeap() {//O(logn)
swap(heap.front(), heap.back());
heapAdjust(heap, 0, heap.size() - 2);
heap.pop_back();
}
void pushHeap(int num) {//O(logn)
heap.push_back(num);
int s = heap.size() - 1;
int r = (heap.size() - 2) / 2;//获取s的根节点索引
while (r >= 0 && cmp(heap[r], heap[s])) {//如果后进来的s 大于/小于 r,进行置换,并向上一层递进
swap(heap[r], heap[s]);
s = r; r = (s - 1) / 2; //递进
}
}
};
int main() {
vector<int> vtTest = { 50,10,90,30,70,40,80,60,20 };
Heap<myless> bigheap(vtTest);
bigheap.heapBuild();
for_each(vtTest.begin(), vtTest.end(), [](int num) {cout << num << " "; }); cout << endl;
bigheap.popHeap();
for_each(vtTest.begin(), vtTest.end(), [](int num) {cout << num<< " "; }); cout << endl;
cout << "--------------大堆下排序-------------" << endl;
bigheap.heapSort();
for_each(vtTest.begin(), vtTest.end(), [](int num) {cout << num << " "; }); cout << endl;
cout << "--------------实现小堆下排序-------------" << endl;
Heap<mygreater> smallheap(vtTest);
smallheap.heapSort();
for_each(vtTest.begin(), vtTest.end(), [](int num) {cout << num << " "; }); cout << endl;
system("pause");
}
结果如下:
90 70 80 60 10 40 50 30 20
80 70 50 60 10 40 20 30
--------------大堆下排序-------------
10 20 30 40 50 60 70 80
--------------实现小堆下排序-------------
80 70 60 50 40 30 20 10