• 第六十五课 二叉树中属性操作的实现


    递归功能函数:

    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 }

    结果如下:

  • 相关阅读:
    Mysql命令下导出select查询数据之 select ... into outfile方法
    接口调试工具Postman之自动同步Chrome cookies,实现自动登陆验证
    PHP函数file_get_contents()使用 https 协议时报错:SSL operation failed
    MySQL中连接超时自动断开的解决方案
    UEditor富文本WEB编辑器设置代码高亮
    Laravel 自定义公共函数全局使用,并设置自定加载
    Laravel 解决blade模板转义html标签问题
    PHP 高效导入导出Excel(csv)方法之fgetcsv()和fputcsv()函数
    Mysql命令行tab自动补全方法
    PHP利用get_headers()函数判断远程的url地址是否有效
  • 原文地址:https://www.cnblogs.com/wanmeishenghuo/p/9694776.html
Copyright © 2020-2023  润新知