第六十五课 二叉树中属性操作的实现
Posted wanmeishenghuo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第六十五课 二叉树中属性操作的实现相关的知识,希望对你有一定的参考价值。
递归功能函数:
1 int count(BTreeNode<T>* node) const 2 { 3 return (node != NULL) ? (count(node->left) + count(node->right) + 1) : 0; 4 }
功能函数如下:
1 int height(BTreeNode<T>* node) const 2 { 3 int ret = 0; 4 5 if( node != NULL ) 6 { 7 int lh = height(node->left); 8 int rh = height(node->right); 9 10 ret = ((lh > rh) ? lh : rh) + 1;; 11 } 12 13 return ret; 14 }
degree的递归功能函数如下:
1 int degree(BTreeNode<T>* node) const 2 { 3 int ret = 0; 4 5 if( node != NULL ) 6 { 7 BTreeNode<T>* child[] = {node->left, node->right}; 8 9 ret = (!!node->left + !!node->right); 10 11 for( int i = 0; (i < 2) && (ret < 2); i++) 12 { 13 int d = degree(child[i]); 14 15 if( ret < d ) 16 { 17 ret = d; 18 } 19 } 20 } 21 22 return ret; 23 }
我们去掉了冗余代码,用数组和for循环的方式实现。 如果不用这个方式,将会出现两段相似的代码。
如下:
1 #if 0 2 int degree(BTreeNode<T>* node) const 3 { 4 int ret = 0; 5 6 if( node != NULL ) 7 { 8 int dl = degree(node->left); 9 int dr = degree(node->right); 10 11 ret = (!!node->left + !!node->right); 12 13 if( ret < dl ) 14 { 15 ret = dl; 16 } 17 18 if( ret < dr ) 19 { 20 ret = dr; 21 } 22 } 23 24 return ret; 25 } 26 #endif
总的Btree.h如下:
1 #ifndef BTREE_H 2 #define BTREE_H 3 4 #include "Tree.h" 5 #include "BTreeNode.h" 6 #include "Exception.h" 7 #include "LinkQueue.h" 8 9 10 namespace DTLib 11 { 12 13 template < typename T > 14 class BTree : public Tree<T> 15 { 16 protected: 17 //定义递归功能函数 18 virtual BTreeNode<T>* find(BTreeNode<T>* node, const T& value) const 19 { 20 BTreeNode<T>* ret = NULL; 21 22 if( node != NULL ) 23 { 24 if( node->value == value ) 25 { 26 ret = node; 27 } 28 else 29 { 30 if( ret == NULL ) 31 { 32 ret = find(node->left, value); 33 } 34 35 if( ret == NULL ) 36 { 37 ret = find(node->right, value); 38 } 39 } 40 } 41 42 return ret; 43 } 44 45 virtual BTreeNode<T>* find(BTreeNode<T>* node, BTreeNode<T>* obj) const 46 { 47 BTreeNode<T>* ret = NULL; 48 49 if( node == obj ) 50 { 51 ret = node; 52 } 53 else 54 { 55 if( node != NULL ) 56 { 57 if( ret == NULL ) 58 { 59 ret = find(node->left, obj); 60 } 61 62 if( ret == NULL ) 63 { 64 ret = find(node->right, obj); 65 } 66 } 67 } 68 69 return ret; 70 } 71 72 virtual bool insert(BTreeNode<T>* n, BTreeNode<T>* np, BTNodePos pos) 73 { 74 bool ret = true; 75 76 if( pos == ANY ) 77 { 78 if( np->left == NULL ) 79 { 80 np->left = n; 81 } 82 else if( np->right == NULL ) 83 { 84 np->right = n; 85 } 86 else 87 { 88 ret = false; 89 } 90 } 91 else if( pos == LEFT ) 92 { 93 if( np->left == NULL ) 94 { 95 np->left = n; 96 } 97 else 98 { 99 ret = false; 100 } 101 } 102 else if( pos == RIGHT ) 103 { 104 if( np->right == NULL ) 105 { 106 np->right = n; 107 } 108 else 109 { 110 ret = false; 111 } 112 } 113 else 114 { 115 ret = false; 116 } 117 118 return ret; 119 } 120 121 virtual void remove(BTreeNode<T>* node, BTree<T>*& ret) 122 { 123 ret = new BTree<T>(); 124 125 if( ret == NULL ) 126 { 127 THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create btree..."); 128 } 129 else 130 { 131 if( root() == node ) 132 { 133 this->m_root = NULL; 134 } 135 else 136 { 137 BTreeNode<T>* parent = dynamic_cast<BTreeNode<T>*>(node->parent); 138 139 if( parent->left == node ) 140 { 141 parent->left = NULL; 142 } 143 else if( parent->right == node ) 144 { 145 parent->right = NULL; 146 } 147 148 node->parent = NULL; 149 } 150 151 ret->m_root = node; //作为子树返回 152 } 153 } 154 155 virtual void free(BTreeNode<T>* node) 156 { 157 if( node != NULL ) 158 { 159 free(node->left); 160 free(node->right); 161 162 if( node->flag() ) 163 { 164 delete node; 165 } 166 } 167 } 168 #if 0 169 int count(BTreeNode<T>* node) const 170 { 171 int ret = 0; 172 173 if( node != NULL ) 174 { 175 ret = count(node->left) + count(node->right) + 1; 176 } 177 178 return ret; 179 } 180 #endif 181 182 int count(BTreeNode<T>* node) const 183 { 184 return (node != NULL) ? (count(node->left) + count(node->right) + 1) : 0; 185 } 186 187 int height(BTreeNode<T>* node) const 188 { 189 int ret = 0; 190 191 if( node != NULL ) 192 { 193 int lh = height(node->left); 194 int rh = height(node->right); 195 196 ret = ((lh > rh) ? lh : rh) + 1;; 197 } 198 199 return ret; 200 } 201 202 #if 0 203 int degree(BTreeNode<T>* node) const 204 { 205 int ret = 0; 206 207 if( node != NULL ) 208 { 209 int dl = degree(node->left); 210 int dr = degree(node->right); 211 212 ret = (!!node->left + !!node->right); 213 214 if( ret < dl ) 215 { 216 ret = dl; 217 } 218 219 if( ret < dr ) 220 { 221 ret = dr; 222 } 223 } 224 225 return ret; 226 } 227 #endif 228 //二叉树的最大度数为2,上面的实现效率太低 229 int degree(BTreeNode<T>* node) const 230 { 231 int ret = 0; 232 233 if( node != NULL ) 234 { 235 BTreeNode<T>* child[] = {node->left, node->right}; 236 237 ret = (!!node->left + !!node->right); 238 239 for( int i = 0; (i < 2) && (ret < 2); i++) 240 { 241 int d = degree(child[i]); 242 243 if( ret < d ) 244 { 245 ret = d; 246 } 247 } 248 } 249 250 return ret; 251 } 252 public: 253 bool insert(TreeNode<T>* node) 254 { 255 return insert(node, ANY); 256 } 257 258 virtual bool insert(TreeNode<T>* node, BTNodePos pos) 259 { 260 bool ret = true; 261 262 if( node != NULL ) 263 { 264 if( this->m_root == NULL ) //空树 265 { 266 node->parent = NULL; 267 this->m_root = node; 268 } 269 else 270 { 271 BTreeNode<T>* np = find(node->parent); 272 273 if( np != NULL ) 274 { 275 ret = insert(dynamic_cast<BTreeNode<T>*>(node), np, pos); 276 } 277 else 278 { 279 THROW_EXCEPTION(InvalidParameterException, "invalid parent tree node..."); 280 } 281 } 282 } 283 else 284 { 285 THROW_EXCEPTION(InvalidParameterException, "parameter node can not be null..."); 286 } 287 288 return ret; 289 } 290 291 bool insert(const T& value, TreeNode<T>* parent) 292 { 293 return insert(value, parent, ANY); 294 } 295 296 virtual bool insert(const T& value, TreeNode<T>* parent, BTNodePos pos) 297 { 298 bool ret = true; 299 BTreeNode<T>* node = BTreeNode<T>::NewNode(); 300 301 if( node == NULL ) 302 { 303 THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create node..."); 304 } 305 else 306 { 307 node->value = value; 308 node->parent = parent; 309 310 ret = insert(node, pos); 311 312 if( !ret ) 313 { 314 delete node; 315 } 316 } 317 318 return ret; 319 } 320 321 SharedPointer< Tree<T> > remove(TreeNode<T>* node) //删除的节点的子节点我们还需要处理,因此要返回删除节点的指针,//这样有机会对里面的元素做进一步操作 322 { 323 BTree<T>* ret = NULL; 324 325 node = find(node); 326 327 if( node == NULL ) 328 { 329 THROW_EXCEPTION(InvalidParameterException, "parameter is invalid..."); 330 } 331 else 332 { 333 remove(dynamic_cast<BTreeNode<T>*>(node), ret); 334 } 335 336 return ret; 337 } 338 339 SharedPointer< Tree<T> > remove(const T& value) 340 { 341 BTree<T>* ret = NULL; 342 343 BTreeNode<T>* node = find(value); 344 345 if( node == NULL ) 346 { 347 THROW_EXCEPTION(InvalidParameterException, "can not find node via value..."); 348 } 349 else 350 { 351 remove(node, ret); 352 } 353 354 return ret; 355 } 356 357 BTreeNode<T>* find(const T& value) const 358 { 359 return find(root(), value); 360 } 361 362 BTreeNode<T>* find(TreeNode<T>* node) const 363 { 364 return find(root(), dynamic_cast<BTreeNode<T>*>(node)); 365 } 366 367 BTreeNode<T>* root() const 368 { 369 return dynamic_cast<BTreeNode<T>*>(this->m_root); 370 } 371 372 int degree() const 373 { 374 return degree(root()); 375 } 376 377 int count() const 378 { 379 return count(root()); 380 } 381 382 int height() const 383 { 384 return height(root()); 385 } 386 387 void clear() 388 { 389 free(root()); 390 391 this->m_root = NULL; 392 } 393 394 ~BTree() 395 { 396 clear(); 397 } 398 }; 399 400 } 401 402 #endif // BTREE_H
测试程序如下:
1 #include <iostream> 2 #include "GTree.h" 3 #include "GTreeNode.h" 4 #include "BTree.h" 5 #include "BTreeNode.h" 6 7 8 using namespace std; 9 using namespace DTLib; 10 11 12 int main() 13 { 14 BTree<int> bt; 15 BTreeNode<int>* n = NULL; 16 17 bt.insert(1, NULL); 18 19 n = bt.find(1); 20 bt.insert(2, n); 21 bt.insert(3, n); 22 23 n = bt.find(2); 24 bt.insert(4, n); 25 bt.insert(5, n); 26 27 n = bt.find(4); 28 bt.insert(8, n); 29 bt.insert(9, n); 30 31 n = bt.find(5); 32 bt.insert(10, n); 33 34 n = bt.find(3); 35 bt.insert(6, n); 36 bt.insert(7, n); 37 38 39 cout << bt.count() << endl; 40 cout << bt.height() << endl; 41 cout << bt.degree() << endl; 42 43 int a[] = {8, 9, 10, 11, 7}; 44 45 SharedPointer< Tree<int> > sp = bt.remove(3); 46 47 for(int i = 0; i < 5; i++) 48 { 49 TreeNode<int>* node = bt.find(a[i]); 50 51 while( node ) 52 { 53 cout << node->value << " "; 54 node = node->parent; 55 } 56 57 cout << endl; 58 } 59 60 61 return 0; 62 }
结果如下:
以上是关于第六十五课 二叉树中属性操作的实现的主要内容,如果未能解决你的问题,请参考以下文章
剑指Offer(Java版)第六十五题:给定一棵二叉搜索树,请找出其中的第k小的结点。 例如, (5,3,7,2,4,6,8) 中,按结点数值大小顺序第三小结点的值为4。