zoukankan      html  css  js  c++  java
  • 第六十六课 二叉树结构的层次遍历

     

    GTree和BTree中都有遍历相关的函数,因此,我们将这些遍历相关的函数放到Tree.h中,作为纯虚函数声明:

    如下:

     1 virtual bool insert(TreeNode<T>* node) = 0;
     2     virtual bool insert(const T& value, TreeNode<T>* parent) = 0;
     3     virtual SharedPointer< Tree<T> > remove(const T& value) = 0; //删除的节点的子节点我们还需要处理,因此要返回删除节点的指针,
     4                                                                 //这样有机会对里面的元素做进一步操作
     5     virtual SharedPointer< Tree<T> > remove(TreeNode<T>* node) = 0;
     6     virtual TreeNode<T>* find(const T& value) const = 0;
     7     virtual TreeNode<T>* find(TreeNode<T>* node) const = 0;
     8     virtual TreeNode<T>* root() const = 0;
     9     virtual int degree() const = 0;
    10     virtual int count() const = 0;
    11     virtual int height() const = 0;
    12     virtual void clear() = 0;
    13     virtual bool begin() = 0;
    14     virtual bool end() = 0;
    15     virtual bool next() = 0;
    16     virtual T current() = 0;

    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     LinkQueue<BTreeNode<T>*> m_queue;
     18     //定义递归功能函数
     19     virtual BTreeNode<T>* find(BTreeNode<T>* node, const T& value) const
     20     {
     21         BTreeNode<T>* ret = NULL;
     22 
     23         if( node != NULL )
     24         {
     25             if( node->value == value )
     26             {
     27                 ret = node;
     28             }
     29             else
     30             {
     31                 if( ret == NULL )
     32                 {
     33                     ret = find(node->left, value);
     34                 }
     35 
     36                 if( ret == NULL )
     37                 {
     38                     ret = find(node->right, value);
     39                 }
     40             }
     41         }
     42 
     43         return ret;
     44     }
     45 
     46     virtual BTreeNode<T>* find(BTreeNode<T>* node, BTreeNode<T>* obj) const
     47     {
     48         BTreeNode<T>* ret = NULL;
     49 
     50         if( node == obj )
     51         {
     52             ret = node;
     53         }
     54         else
     55         {
     56             if( node != NULL )
     57             {
     58                 if( ret == NULL )
     59                 {
     60                     ret = find(node->left, obj);
     61                 }
     62 
     63                 if( ret == NULL )
     64                 {
     65                     ret = find(node->right, obj);
     66                 }
     67             }
     68         }
     69 
     70         return ret;
     71     }
     72 
     73     virtual bool insert(BTreeNode<T>* n, BTreeNode<T>* np, BTNodePos pos)
     74     {
     75         bool ret = true;
     76 
     77         if( pos == ANY )
     78         {
     79             if( np->left == NULL )
     80             {
     81                 np->left = n;
     82             }
     83             else if( np->right == NULL )
     84             {
     85                 np->right = n;
     86             }
     87             else
     88             {
     89                 ret = false;
     90             }
     91         }
     92         else if( pos == LEFT )
     93         {
     94             if( np->left == NULL )
     95             {
     96                 np->left = n;
     97             }
     98             else
     99             {
    100                 ret = false;
    101             }
    102         }
    103         else if( pos == RIGHT )
    104         {
    105             if( np->right == NULL )
    106             {
    107                 np->right = n;
    108             }
    109             else
    110             {
    111                 ret = false;
    112             }
    113         }
    114         else
    115         {
    116             ret = false;
    117         }
    118 
    119         return ret;
    120     }
    121 
    122     virtual void remove(BTreeNode<T>* node, BTree<T>*& ret)
    123     {
    124         ret = new BTree<T>();
    125 
    126         if( ret == NULL )
    127         {
    128             THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create btree...");
    129         }
    130         else
    131         {
    132             if( root() == node )
    133             {
    134                 this->m_root = NULL;
    135             }
    136             else
    137             {
    138                 BTreeNode<T>* parent = dynamic_cast<BTreeNode<T>*>(node->parent);
    139 
    140                 if( parent->left == node )
    141                 {
    142                     parent->left = NULL;
    143                 }
    144                 else if( parent->right == node )
    145                 {
    146                     parent->right = NULL;
    147                 }
    148 
    149                 node->parent = NULL;
    150             }
    151 
    152             ret->m_root = node;  //作为子树返回
    153         }
    154     }
    155 
    156     virtual void free(BTreeNode<T>* node)
    157     {
    158         if( node != NULL )
    159         {
    160             free(node->left);
    161             free(node->right);
    162 
    163             if( node->flag() )
    164             {
    165                 delete node;
    166             }
    167         }
    168     }
    169     #if 0
    170     int count(BTreeNode<T>* node) const
    171     {
    172         int ret = 0;
    173 
    174         if( node != NULL )
    175         {
    176             ret = count(node->left) + count(node->right) + 1;
    177         }
    178 
    179         return ret;
    180     }
    181     #endif
    182 
    183     int count(BTreeNode<T>* node) const
    184     {
    185         return (node != NULL) ? (count(node->left) + count(node->right) + 1) : 0;
    186     }
    187 
    188     int height(BTreeNode<T>* node) const
    189     {
    190         int ret = 0;
    191 
    192         if( node != NULL )
    193         {
    194             int lh = height(node->left);
    195             int rh = height(node->right);
    196 
    197             ret = ((lh > rh) ? lh : rh) + 1;;
    198         }
    199 
    200         return ret;
    201     }
    202 
    203 #if 0
    204     int degree(BTreeNode<T>* node) const
    205     {
    206         int ret = 0;
    207 
    208         if( node != NULL )
    209         {
    210             int dl = degree(node->left);
    211             int dr = degree(node->right);
    212 
    213             ret = (!!node->left + !!node->right);
    214 
    215             if( ret < dl )
    216             {
    217                 ret = dl;
    218             }
    219 
    220             if( ret < dr )
    221             {
    222                 ret = dr;
    223             }
    224         }
    225 
    226         return ret;
    227     }
    228 #endif
    229 //二叉树的最大度数为2,上面的实现效率太低
    230     int degree(BTreeNode<T>* node) const
    231     {
    232         int ret = 0;
    233 
    234         if( node != NULL )
    235         {
    236             BTreeNode<T>* child[] = {node->left, node->right};
    237 
    238             ret = (!!node->left + !!node->right);
    239 
    240             for( int i = 0; (i < 2) && (ret < 2); i++)
    241             {
    242                 int d = degree(child[i]);
    243 
    244                 if( ret < d )
    245                 {
    246                     ret = d;
    247                 }
    248             }
    249         }
    250 
    251         return ret;
    252     }
    253 public:
    254     bool insert(TreeNode<T>* node)
    255     {
    256         return insert(node, ANY);
    257     }
    258 
    259     virtual bool insert(TreeNode<T>* node, BTNodePos pos)
    260     {
    261         bool ret = true;
    262 
    263         if( node != NULL )
    264         {
    265             if( this->m_root == NULL )  //空树
    266             {
    267                 node->parent = NULL;
    268                 this->m_root = node;
    269             }
    270             else
    271             {
    272                 BTreeNode<T>* np = find(node->parent);
    273 
    274                 if( np != NULL )
    275                 {
    276                     ret = insert(dynamic_cast<BTreeNode<T>*>(node), np, pos);
    277                 }
    278                 else
    279                 {
    280                     THROW_EXCEPTION(InvalidParameterException, "invalid parent tree node...");
    281                 }
    282             }
    283         }
    284         else
    285         {
    286             THROW_EXCEPTION(InvalidParameterException, "parameter node can not be null...");
    287         }
    288 
    289         return ret;
    290     }
    291 
    292     bool insert(const T& value, TreeNode<T>* parent)
    293     {
    294         return insert(value, parent, ANY);
    295     }
    296 
    297     virtual bool insert(const T& value, TreeNode<T>* parent, BTNodePos pos)
    298     {
    299         bool ret = true;
    300         BTreeNode<T>* node = BTreeNode<T>::NewNode();
    301 
    302         if( node == NULL )
    303         {
    304             THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create node...");
    305         }
    306         else
    307         {
    308             node->value = value;
    309             node->parent = parent;
    310 
    311             ret = insert(node, pos);
    312 
    313             if( !ret )
    314             {
    315                 delete node;
    316             }
    317         }
    318 
    319         return ret;
    320     }
    321 
    322     SharedPointer< Tree<T> > remove(TreeNode<T>* node) //删除的节点的子节点我们还需要处理,因此要返回删除节点的指针,//这样有机会对里面的元素做进一步操作
    323     {
    324         BTree<T>* ret = NULL;
    325 
    326         node = find(node);
    327 
    328         if( node == NULL )
    329         {
    330             THROW_EXCEPTION(InvalidParameterException, "parameter is invalid...");
    331         }
    332         else
    333         {
    334             remove(dynamic_cast<BTreeNode<T>*>(node), ret);
    335 
    336             m_queue.clear();
    337         }
    338 
    339         return ret;
    340     }
    341 
    342     SharedPointer< Tree<T> > remove(const T& value)
    343     {
    344         BTree<T>* ret = NULL;
    345 
    346         BTreeNode<T>* node = find(value);
    347 
    348         if( node == NULL )
    349         {
    350             THROW_EXCEPTION(InvalidParameterException, "can not find node via value...");
    351         }
    352         else
    353         {
    354             remove(node, ret);
    355 
    356             m_queue.clear();
    357         }
    358 
    359         return ret;
    360     }
    361 
    362     BTreeNode<T>* find(const T& value) const
    363     {
    364         return find(root(), value);
    365     }
    366 
    367     BTreeNode<T>* find(TreeNode<T>* node) const
    368     {
    369         return find(root(), dynamic_cast<BTreeNode<T>*>(node));
    370     }
    371 
    372     BTreeNode<T>* root() const
    373     {
    374         return dynamic_cast<BTreeNode<T>*>(this->m_root);
    375     }
    376 
    377     int degree() const
    378     {
    379         return degree(root());
    380     }
    381 
    382     int count() const
    383     {
    384         return count(root());
    385     }
    386 
    387     int height() const
    388     {
    389         return height(root());
    390     }
    391 
    392     void clear()
    393     {
    394         free(root());
    395 
    396         m_queue.clear();
    397 
    398         this->m_root = NULL;
    399     }
    400 
    401     bool begin()
    402     {
    403         bool ret = ( root() != NULL );
    404 
    405         if( ret )
    406         {
    407             m_queue.clear();
    408             m_queue.add(root());
    409         }
    410 
    411         return ret;
    412     }
    413 
    414     bool end()
    415     {
    416         return (m_queue.length() == 0);
    417     }
    418 
    419     bool next()
    420     {
    421         bool ret = (m_queue.length() > 0);
    422 
    423         if( ret )
    424         {
    425             BTreeNode<T>* node = m_queue.front();
    426 
    427             m_queue.remove();  //将对头元素出队,相当于移动游标
    428 
    429             if( node->left != NULL )
    430             {
    431                 m_queue.add(node->left);
    432             }
    433 
    434             if( node->right )
    435             {
    436                 m_queue.add(node->right);
    437             }
    438         }
    439 
    440         return ret;
    441     }
    442 
    443     T current()
    444     {
    445         if( !end() )  //遍历的过程当中调用current函数才有意义
    446         {
    447             return m_queue.front()->value;
    448         }
    449         else
    450         {
    451             THROW_EXCEPTION(InvalidOperationException, "No value at current position...");
    452         }
    453     }
    454 
    455     ~BTree()
    456     {
    457         clear();
    458     }
    459 };
    460 
    461 }
    462 
    463 #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 
    62     cout << endl;
    63 
    64     for(bt.begin(); !bt.end(); bt.next())
    65     {
    66         cout << bt.current() << " ";
    67     }
    68 
    69     cout << endl;
    70 
    71     return 0;
    72 }

    结果如下:

  • 相关阅读:
    layui timeline使用
    Java随机数使用
    Matlab信号处理工具箱函数
    高斯白噪声(white Gaussian noise,WGN)
    概率分布之间的距离度量以及python实现
    Wasserstein距离 和 Lipschitz连续
    线性分式变换(linear fractional transformation)
    算法的时间复杂度和空间复杂度-总结
    随机森林(Random Forest,简称RF)
    增强学习与马尔科夫决策过程
  • 原文地址:https://www.cnblogs.com/wanmeishenghuo/p/9694871.html
Copyright © 2011-2022 走看看