zoukankan      html  css  js  c++  java
  • 第六十七课 二叉树的典型遍历方式

     

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

    结果如下:

    小结:

  • 相关阅读:
    UniGui使用IconFont图标(新)
    uniGUI uniEdit回车键处理遇到的问题
    War包的目录结构
    FAT32和NTFS最大支持的单个文件大小分别是多大?
    释放 MappedByteBuffer映射的内存
    C#基础篇 正则表达式入门
    JAVA获取文件MD5值
    C#正则表达式语法规则详解
    MD5加密算法原理及实现
    Java 文件名操作的相关工具类 & Java中windows路径转换成linux路径等工具类
  • 原文地址:https://www.cnblogs.com/wanmeishenghuo/p/9694898.html
Copyright © 2011-2022 走看看