博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
左偏树
阅读量:5314 次
发布时间:2019-06-14

本文共 4838 字,大约阅读时间需要 16 分钟。

首先声明,我的代码基本是照着www.cnblogs.com/skywang12345/p/3638342.html打的,感谢分享。

不过我的疑问是在实现merge时提供的形参为何要加引用,一开始傻乎乎地觉得这样才能真正改动内部指针成员,知道去掉引用run了一把才知道不加引用也能实现合并,加引用除了减少拷贝指针的开销其实没有其他好处了,当然只是我个人的想法,望轻喷。传值调用也能改变内部指针指向的原因是这两条语句,mRoot=rhs->mRoot;x->right=merge(x->right,y);

虽然改变的是局部指针的指向,但由于又进行了一次赋值操作,所以实参pointer也被改变了指向。相当于创建两个局部指针作为实参的拷贝,merge后形成一颗新的左偏树再传给实参。虽然cppprimer还没看到后面,也通过上面的博客大概知道了用法,再表感激。下面贴自己搬运后略微修改的代码:

1 #include 
2 #include
3 4 using namespace std; 5 6 template
7 class LeftistNode { 8 public: 9 T key; 10 int npl; 11 LeftistNode* left; 12 LeftistNode* right; 13 14 LeftistNode(T value = -1, LeftistNode* l = 0, LeftistNode* r = 0) ://key值默认为-1 15 key(value), left(l), right(r), npl(0) {} 16 }; 17 18 template
19 class LeftistHeap { 20 private: 21 LeftistNode
*mRoot; 22 public: 23 //构造函数 24 LeftistHeap() :mRoot(0) {} 25 ~LeftistHeap();//析构函数 26 27 void preOrder();//前序遍历“左倾堆” 28 29 void merge(LeftistHeap
* other);//将自己与other堆合并 30 void insert(T key); 31 void remove();//只支持删除堆顶 32 void destroy(); 33 // 打印左倾堆 34 void print(); 35 36 private: 37 void preOrder(LeftistNode
* heap)const; 38 //如果不解引用指针与其他类型的swap无区别 39 void swapNode(LeftistNode
* &x, LeftistNode
* &y); 40 LeftistNode
* merge(LeftistNode
* x, LeftistNode
* y); 41 LeftistNode
* insert(LeftistNode
* heap, T key); 42 LeftistNode
* remove(LeftistNode
* heap); 43 44 void destroy(LeftistNode
* heap); 45 // 打印左倾堆 46 void print(LeftistNode
* heap, T key, int direction); 47 }; 48 49 template
50 LeftistHeap
::~LeftistHeap() { destroy(); } 51 52 template
53 void LeftistHeap
::preOrder(LeftistNode
* heap)const { 54 if (heap) { 55 cout << heap->key << endl; 56 preOrder(heap->left); 57 preOrder(heap->right); 58 } 59 } 60 61 template
62 void LeftistHeap
::preOrder() { 63 preOrder(mRoot); 64 } 65 66 template
67 void LeftistHeap
::swapNode(LeftistNode
* &x, LeftistNode
* &y) { 68 LeftistNode
* tmp = x; 69 x = y; 70 y = tmp; 71 } 72 73 template
74 LeftistNode
* LeftistHeap
::merge(LeftistNode
* x, LeftistNode
* y) { 75 if (x == NULL)return y; 76 if (y == NULL)return x; 77 78 if (x->key > y->key)swapNode(x, y); 79 x->right = merge(x->right, y); 80 81 if (x->left == 0 || x->left->npl < x->right->npl)swapNode(x->left, x->right);//保证左偏 82 83 if (x->right == 0)x->npl = 0; 84 else x->npl = x->right->npl + 1; 85 86 return x; 87 } 88 89 template
90 void LeftistHeap
::merge(LeftistHeap
*rhs) { 91 mRoot = merge(mRoot, rhs->mRoot);// 92 } 93 94 template
95 LeftistNode
* LeftistHeap
::insert(LeftistNode
* heap, T key) { 96 LeftistNode
* node = new LeftistNode
(key, 0, 0); 97 if (node == 0) { 98 cout << "create node failed!" << endl; 99 return heap;100 }101 102 return merge(heap, node);103 }104 105 template
106 void LeftistHeap
::insert(T key) {107 mRoot = insert(mRoot, key);108 }109 110 template
111 LeftistNode
* LeftistHeap
::remove(LeftistNode
* heap) {112 LeftistNode
* l = heap->left;113 LeftistNode
* r = heap->right;114 115 delete heap;116 //heap = 0;//置空117 return merge(l, r);118 }119 120 template
121 void LeftistHeap
::remove() { mRoot = remove(mRoot); }122 123 template
124 void LeftistHeap
::destroy(LeftistNode
* heap) {125 if (heap == 0)return;126 127 destroy(heap->left);128 destroy(heap->right);129 130 delete heap;131 }132 133 template
134 void LeftistHeap
::print(LeftistNode
* heap, T key, int direction)135 {136 if (heap != NULL)137 {138 if (direction == 0) // heap是根节点139 cout << setw(2) << heap->key << "(" << heap->npl << ") is root" << endl;140 else // heap是分支节点141 cout << setw(2) << heap->key << "(" << heap->npl << ") is " << setw(2) << key << "'s " << setw(12) << (direction == 1 ? "right child" : "left child") << endl;142 143 print(heap->left, heap->key, -1);144 print(heap->right, heap->key, 1);145 }146 }147 148 template
149 void LeftistHeap
::print()150 {151 if (mRoot != NULL)152 print(mRoot, mRoot->key, 0);153 }154 155 156 template
157 void LeftistHeap
::destroy() { destroy(mRoot); }158 159 int main(void) {160 int i;161 int a[] = { 10,40,24,30,36,20,12,16 };162 int b[] = { 17,13,11,15,19,21,23 };163 int alen = sizeof(a) / sizeof(a[0]);164 int blen = sizeof(b) / sizeof(b[0]);165 LeftistHeap
* ha = new LeftistHeap
();166 LeftistHeap
* hb = new LeftistHeap
();167 168 cout << "== 左倾堆(ha)中依次添加: ";169 for (i = 0; i
insert(a[i]);173 }174 cout << "\n== 左倾堆(ha)的详细信息: " << endl;175 ha->print();176 177 178 cout << "\n== 左倾堆(hb)中依次添加: ";179 for (i = 0; i
insert(b[i]);183 }184 cout << "\n== 左倾堆(hb)的详细信息: " << endl;185 hb->print();186 187 188 // 将"左倾堆hb"合并到"左倾堆ha"中。189 ha->merge(hb);190 cout << "\n== 合并ha和hb后的详细信息: " << endl;191 ha->print();192 193 194 // 销毁195 ha->destroy();196 197 return 0;198 199 }

 

转载于:https://www.cnblogs.com/schsb/p/8595071.html

你可能感兴趣的文章
《数据分析实战》--第三章 python实现
查看>>
crontab command not found
查看>>
记录-springMVC访问web-inf下文件问题+在jsp页面导入jquery插件路径不对问题
查看>>
对于C语言中数组名是指针的理解
查看>>
实验八 接口与实现接口的类
查看>>
mac OSx 安装 mysqlclient
查看>>
Scala for the Impatients---(10)Traits
查看>>
简单的姓名号码查询系统
查看>>
PostgreSQL 保留关键字添加方法之一,不带参数的函数
查看>>
你的博客可能被爬了
查看>>
赛前热手 (天梯赛暴力题)
查看>>
.net 冒泡排序示例
查看>>
Uva(10330)
查看>>
vlan学习
查看>>
R-Sys.time计算程序运行时间
查看>>
Java类模板
查看>>
【转贴】SAP HANA内存数据库详解
查看>>
二分查找BinarySearch(Java)
查看>>
两种应该掌握的排序方法--------1.shell Sort
查看>>
vuejs动态组件给子组件传递数据
查看>>