您好,登錄后才能下訂單哦!
一、用模版實現大小堆
如果不用模版的話,寫大小堆,就需要分別實現兩次,但是應用模版的話問題就簡單多了,我們只需要實現兩個仿函數,Greater和Less就行了,仿函數就是用類實現一個()的重載就實現了仿函數。這個看下代碼就能理解了。再設計參數的時候,需要把模版設計成模版的模版參數,因為要實現大小堆嘛!當我們實現好一個大堆或者小隊的邏輯后只需要用模版接收的Greater或Less類定義一個變量,就能實現通用功能了。
template<typename T> struct Less { bool operator()(const T& l, const T& r) { return l < r; } }; template<class T> struct Greater { bool operator()(const T& l, const T& r) { return l>r; } }; template <class T,template<class> class compare = less> class Heap { public: Heap() {} Heap(T* a,size_t size) { size_t index = 0; while (index < size) { _a.push_back(a[index]); index++; } for (int i = (_a.size() - 2) / 2; i >= 0; i--) _AdjustDown(i); } void push(const T& x) { _a.push_back(x); _AdjustUp(_a.size() -1); } void pop() { size_t size = _a.size(); assert(size > 0); swap(_a[0], _a[size - 1]); _a.pop_back(); size = _a.size(); _AdjustDown(0); } size_t top() { assert(!_a.empty()); return _a[0]; } bool empty() { return _a.size() == 0; } size_t Size() { return _a.size(); } void Print() { for (int i = 0; i < _a.size(); i++) { cout << _a[i] << " "; } cout << endl; } protected: void _AdjustUp(int child) { int parent = (child - 1) / 2; compare<T> com; //如果是大堆傳過來就是用大堆的邏輯,小堆就實現小堆的邏輯 while (child > 0) { //找出孩子中的最大孩子 if (com(_a[child] , _a[parent])) { swap(_a[child], _a[parent]); child = parent; parent = (child - 1) / 2; } else { break; } } } void _AdjustDown(size_t parent) { size_t child = 2 * parent + 1; compare<T> com; //如果是大堆傳過來就是用大堆的邏輯,小堆就實現小堆的邏輯 while (child < _a.size()) { //找出孩子中的最大孩子 if (child + 1 < _a.size() && com(_a[child+1] ,_a[child])) { ++child; } //把 if (com(_a[child] , _a[parent])) { swap(_a[parent], _a[child]); parent = child; child = child * 2 + 1; } else { break; } } } protected: vector<T> _a; };
二、用模版實現優先級隊列
前面實現了大小堆,這里我們可以使用適配器,直接調用大小堆,來實現優先級隊列。
template<class T, template<class> class compare = Less> class priorityQueue { private: Heap<T, compare> _hp; public: void push(const T& x) { _hp.push(x); } void pop() { _hp.pop(); } T& Top() { return _hp.top(); } void Print() { _hp.Print(); } };
三、堆排序的實現
堆排序的實現簡單思路,(升序)先構造出來一個大堆,調整堆后,將堆頭和最后一個數據交換,最大值就換到了數組的最后,然后在調整堆,但是size需要減少1,因為最大的已經調整到最后,如果再加上它調整又會回到堆頭。
int*& HeapSort(int* a, size_t size) { for (int i = (size - 2) / 2; i >= 0; i--) { _AdjustDown(a, size, i); } for (int i = 0; i < size; i++) { swap(a[0], a[size - i - 1]); _AdjustDown(a, size - i - 1, 0); } return a; }
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。