左式堆 斜堆

來源:互聯網
上載者:User

heap.h

#ifndef _LEFTISTHEAP_H#define _LEFTISTHEAP_Husing namespace std;//虛基類class baseHeap {public:virtual void insert(int x) = 0;};//普通最小堆class heap:public baseHeap {public:int size;int *a;   //儲存資料heap(int n=10000);     //建構函式void merge(const heap &h);  //與現有堆合并void insert(int x);   //插入};//左式堆class leftistHeap:public baseHeap {struct leftistHeapNode {  //結點int element; //元素leftistHeapNode *left; //左孩子leftistHeapNode *right; //右孩子int npl; //零路徑長leftistHeapNode(int x); //建構函式};public:leftistHeapNode *root; //根節點leftistHeap(leftistHeapNode *root = nullptr); //建構函式static leftistHeapNode* Merge(leftistHeapNode* h1, leftistHeapNode* h2);//合并(實現函數)void merge(const leftistHeap &h);//與現有堆合并(介面函數)void insert(int x); //插入};//斜堆class skewHeap:public baseHeap{struct skewHeapNode { //結點int element;  //元素skewHeapNode *left;  //左孩子skewHeapNode *right;  //右孩子skewHeapNode(int x);  //建構函式};public:skewHeapNode *root;  //根節點skewHeap(skewHeapNode* root = nullptr); //建構函式static skewHeapNode* Merge(skewHeapNode* h1, skewHeapNode* h2); //合并(實現函數)void merge(const skewHeap &h);//與現有堆合并(介面函數)void insert(int x); //插入};//全域合并函數const skewHeap &merge(const skewHeap &h1, const skewHeap &h2); const leftistHeap &merge(const leftistHeap &h1, const leftistHeap &h2); const heap &merge(const heap &h1, const heap &h2);  void print(heap h);//列印堆(用於測試)#endif

tmplate.h

#ifndef _TEMPLATE_H#define _TEMPLATE_H#include"heap.h"#include<queue>#include<iostream>// 列印堆(左式堆,斜堆) 用於測試// 層序遍曆,按層輸出template<typename T>void print(T root){if (!root)return;int cur = 1;int curnum = 1;int nextnum = 0;queue<T>q; //隊列q.push(root);while (!q.empty()) { //非空時curnum--;T tmp = q.front();  //當前隊頭元素出隊列cout << tmp->element << " ";q.pop();if (tmp->left) {q.push(tmp->left); //左孩子入隊列nextnum++;}if (tmp->right) {q.push(tmp->right);  //右孩子入隊列nextnum++;}if (curnum == 0) {  //控制按層輸出cout << endl;cur++;curnum = nextnum;nextnum = 0;}}cout << endl;}//交換孩子template<typename T>void swapChild(T &h){T tmp;tmp = h->right;h->right = h->left;h->left = tmp;}#endif

heap.cpp

#include"heap.h"#include<queue>#include<cstdlib>#include<climits>#include<iostream>using namespace std;heap::heap(int n) :size(0) {a = (int*)malloc(sizeof(int)*(n+1));a[0] = INT_MIN;if (!a)printf("error\n");}//初始化大小為0,哨兵為最小值void heap::merge(const heap &h){int i;//直接將外部堆插入for (i = 1; i != size; i++) {insert(h.a[i]);}}const heap& merge(const heap &h1, const heap &h2){int i;heap *tmp = new heap(h1.size+h2.size);//建立一個堆for (i = 1; i <= h1.size; i++) { //插入第一個堆tmp->insert(h1.a[i]);}for (i = 1; i <= h2.size; i++) { //插入第二個堆tmp->insert(h2.a[i]);}return *tmp; //返回建立堆}void heap::insert(int x){int p = ++size; //大小加1a[p] = x;  //插入int tmp = a[p];for (; a[p / 2]>tmp; p /= 2) { //調整位置a[p] = a[p / 2];}a[p] = tmp;}void print(heap h){int i;for (i = 1; i < h.size; i++) { //遍曆輸出cout << h.a[i] << " ";}cout << endl;}

letist heap.cpp

#include"heap.h"#include"template.h"using namespace std;leftistHeap::leftistHeap(leftistHeapNode *root):root(root) { }leftistHeap::leftistHeapNode::leftistHeapNode(int x){element = x; //賦值left = right = nullptr; //左右孩子設為空白npl = 0; //零路徑長初始化為0}leftistHeap::leftistHeapNode* leftistHeap::Merge(leftistHeapNode* h1, leftistHeapNode* h2){if (!h1) return h2; //h1為空白,返回h2if (!h2) return h1; //h2為空白,返回h1if (h1->element > h2->element) { //維護h1的元素始終小於h2leftistHeapNode* tmp = h2;h2 = h1;h1 = tmp;}if (!h1->left)h1->left = h2; //如果h1沒有左孩子,讓h2成為h1的左孩子else { //如果h1有左孩子h1->right = Merge(h1->right, h2);  //合并h1的右孩子和h2if (h1->left->npl<h1->right->npl)swapChild(h1);  //如果左式堆性質被破壞,即左孩子的零路徑長小於右孩子,交換左右孩子h1->npl = h1->right->npl + 1; //更新h1的零路徑長}return h1;}const leftistHeap &merge(const leftistHeap &h1, const leftistHeap &h2){//將傳回值leftistHeapNode轉換成leftistHeap,實現標準化介面leftistHeap *ans=new leftistHeap(leftistHeap::Merge(h1.root, h2.root));return *ans;}void leftistHeap::merge(const leftistHeap &h){//調用已有mergeroot = Merge(root, h.root);}void leftistHeap::insert(int x){if (!root) { //不存在根節點,建立root = new leftistHeapNode(x);}else { //否則,將新節點和原堆合并leftistHeapNode *tmp = new leftistHeapNode(x);root = Merge(root, tmp);}}

skewheap.cpp

#include"heap.h"#include"template.h"using namespace std;skewHeap::skewHeap(skewHeapNode* root):root(root) { }skewHeap::skewHeapNode::skewHeapNode(int x){element = x;   //賦值left = right = nullptr;   //左右孩子都為空白}skewHeap::skewHeapNode* skewHeap::Merge(skewHeapNode* h1, skewHeapNode* h2){if (!h1) return h2; //h1為空白,返回h2if (!h2) return h1; //h2為空白,返回h1if (h1->element > h2->element) { //維護h1的元素始終小於h2skewHeapNode* tmp = h2;h2 = h1;h1 = tmp;}if (!h1->left)h1->left = h2; //如果h1沒有左孩子,讓h2成為h1的左孩子else {h1->right = Merge(h1->right, h2); //合并h1的右孩子和h2swapChild(h1); //交換孩子}return h1;}const skewHeap &merge(const skewHeap &h1, const skewHeap &h2){//將傳回值skewHeapNode轉換成skewHeap,實現標準化介面skewHeap* ans = new skewHeap(skewHeap::Merge(h1.root, h2.root));return *ans;}void skewHeap::merge(const skewHeap &h) {//調用已有mergeroot = Merge(root, h.root);}void skewHeap::insert(int x){if (!root) {root = new skewHeapNode(x);//不存在根節點,建立}else {  //否則,將新節點和原堆合并skewHeapNode *tmp = new skewHeapNode(x);root = Merge(root,tmp);}}

main.cpp

#include"heap.h"#include"template.h"#include<algorithm>#include<cstdio>#include<chrono>using namespace std;int main(){        srand(unsigned(time(nullptr)));int n = 10000;int i;int count = 0;double sum1=0, sum2=0, sum3=0;//統計三個時間chrono::time_point<chrono::high_resolution_clock> start,end;//開始,結束chrono::duration<double> seconds;//計時while (n) { //n為測試資料大小count++;if (count == 100) { //計算100次後輸出printf("%d:\n%lf,%lf,%lf\n",n, sum1 , sum2 , sum3 );count = 0;n -= 1000; //測試資料減少1000sum1 = 0.0, sum2 = 0.0, sum3 = 0.0; //更新sum為0}leftistHeap h1, h2, h3;skewHeap h4, h5, h6;heap h7(n), h8(n), h9(n);int a[10002];for (i = 0; i < n; i++) {a[i] = 2 * i;}random_shuffle(a, a + n); //產生資料(偶數)for (int i = 0; i < n; i++) {  //產生第一棵樹h1.insert(a[i]);h4.insert(a[i]);h7.insert(a[i]);}for (i = 0; i < n; i++) {a[i] = 2 * i + 1;}random_shuffle(a, a + n); //產生資料(奇數)for (int i = 0; i < n; i++) {  //產生第二棵樹h2.insert(a[i]);h5.insert(a[i]);h8.insert(a[i]);}//計算leftistHeap start = chrono::high_resolution_clock::now();h3 = merge(h1, h2);end = chrono::high_resolution_clock::now();seconds = end - start;sum1 = sum1 + seconds.count();//計算skewHeapstart = chrono::high_resolution_clock::now();h6 = merge(h4, h5);end = chrono::high_resolution_clock::now();seconds = end - start;sum2 = sum2 + seconds.count();//計算heapstart = chrono::high_resolution_clock::now();h9 = merge(h7, h8);end = chrono::high_resolution_clock::now();seconds = end - start;sum3 = sum3 + seconds.count();}system("pause");}

 


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.