• 第五十七课 树中属性操作的实现


    添加count函数:

      1 #ifndef GTREE_H
      2 #define GTREE_H
      3 
      4 #include "Tree.h"
      5 #include "GTreeNode.h"
      6 #include "Exception.h"
      7 
      8 namespace DTLib
      9 {
     10 
     11 template < typename T >
     12 class GTree : public Tree<T>
     13 {
     14 protected:
     15     GTreeNode<T>* find(GTreeNode<T>* node, const T& value) const
     16     {
     17         GTreeNode<T>* ret = NULL;
     18 
     19         if( node != NULL )
     20         {
     21             if( node->value == value )
     22             {
     23                 return node;
     24             }
     25             else
     26             {
     27                 for(node->child.move(0); !node->child.end() && (ret == NULL); node->child.next())
     28                 {
     29                     ret = find(node->child.current(), value);
     30                 }
     31             }
     32         }
     33 
     34         return ret;
     35     }
     36 
     37     GTreeNode<T>* find(GTreeNode<T>* node,  GTreeNode<T>* obj) const
     38     {
     39         GTreeNode<T>* ret = NULL;
     40 
     41         if( node == obj )
     42         {
     43             return node;
     44         }
     45         else
     46         {
     47             if( node != NULL )
     48             {
     49                 for( node->child.move(0); !node->child.end() && (ret == NULL); node->child.next())
     50                 {
     51                     ret = find(node->child.current(), obj);
     52                 }
     53             }
     54         }
     55 
     56         return ret;
     57     }
     58 
     59     void free(GTreeNode<T>* node)
     60     {
     61         if( node != NULL )
     62         {
     63             for(node->child.move(0); !node->child.end(); node->child.next())
     64             {
     65                 free(node->child.current());
     66             }
     67 
     68             if( node->flag() )
     69             {
     70                 delete node;
     71             }
     72         }
     73     }
     74 
     75     void remove(GTreeNode<T>* node, GTree<T>*& ret)
     76     {
     77         ret = new GTree<T>();
     78 
     79         if( ret == NULL )
     80         {
     81             THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create tree...");
     82         }
     83         else
     84         {
     85             if( root() == node )
     86             {
     87                 this->m_root = NULL;
     88             }
     89             else
     90             {
     91                 LinkList<GTreeNode<T>*>& child = dynamic_cast<GTreeNode<T>*>(node->parent)->child;
     92 
     93                 child.remove(child.find(node));
     94 
     95                 node->parent = NULL;
     96             }
     97 
     98             ret->m_root = node;
     99         }
    100     }
    101 
    102     int count(GTreeNode<T>* node) const
    103     {
    104         int ret = 0;
    105 
    106         if( node != NULL )
    107         {
    108             ret = 1;
    109 
    110             //node如果没有孩子,则for不执行
    111             for(node->child.move(0); !node->child.end(); node->child.next())
    112             {
    113                 ret += count(node->child.current());
    114             }
    115         }
    116 
    117         return ret;
    118     }
    119 public:
    120     bool insert(TreeNode<T>* node)
    121     {
    122         bool ret = true;
    123 
    124         if( node != NULL )
    125         {
    126             if( this->m_root == NULL ) //如果待插入节点的父节点为空,则这个节点将为根节点
    127             {
    128                 node->parent = NULL;
    129                 this->m_root = node;
    130             }
    131             else
    132             {
    133                 GTreeNode<T>* np = find(node->parent);
    134 
    135                 if( np != NULL )
    136                 {
    137                     GTreeNode<T>* n = dynamic_cast<GTreeNode<T>*>(node);
    138 
    139                     if( np->child.find(n) < 0 )
    140                     {
    141                         np->child.insert(n);
    142                     }
    143                 }
    144                 else
    145                 {
    146                     THROW_EXCEPTION(InvalidParameterException, "Invalid parent tree node...");
    147                 }
    148             }
    149         }
    150         else
    151         {
    152             THROW_EXCEPTION(InvalidParameterException, "Parameter node cannot be NULL ...");
    153         }
    154 
    155         return ret;
    156     }
    157 
    158     bool insert(const T& value, TreeNode<T>* parent)
    159     {
    160         bool ret = true;
    161 
    162         GTreeNode<T>* node = GTreeNode<T>::NewNode();
    163 
    164         if( node != NULL )
    165         {
    166             node->value = value;
    167             node->parent = parent;
    168 
    169             insert(node);
    170         }
    171         else
    172         {
    173             THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create node ...");
    174         }
    175 
    176         return ret;
    177     }
    178 
    179     //删除的节点的子节点我们还需要处理,因此要返回删除节点的指针,这样有机会对里面的元素做进一步操作
    180     SharedPointer< Tree<T> > remove(const T& value)
    181     {
    182         GTree<T>* ret = NULL;
    183 
    184         GTreeNode<T>* node = find(value);
    185 
    186         if( node == NULL )
    187         {
    188             THROW_EXCEPTION(InvalidParameterException, "can not find the node ...");
    189         }
    190         else
    191         {
    192             remove(node, ret);
    193         }
    194 
    195         return ret;
    196     }
    197 
    198     SharedPointer< Tree<T> > remove(TreeNode<T>* node)
    199     {
    200         GTree<T>* ret = NULL;
    201 
    202         node = find(node);
    203 
    204         if( node == NULL )
    205         {
    206             THROW_EXCEPTION(InvalidParameterException, "parameter node is invalid ...");
    207         }
    208         else
    209         {
    210             remove(dynamic_cast<GTreeNode<T>*>(node), ret);
    211         }
    212 
    213         return ret;
    214     }
    215 
    216     GTreeNode<T>* find(const T& value) const  // 返回GTreeNode,赋值兼容性
    217     {
    218         return find(root(), value);
    219     }
    220 
    221     GTreeNode<T>* find(TreeNode<T>* node) const
    222     {
    223         return find(root(), dynamic_cast<GTreeNode<T>*>(node));
    224     }
    225 
    226     GTreeNode<T>* root() const
    227     {
    228         return dynamic_cast<GTreeNode<T>*>(this->m_root);
    229     }
    230 
    231     int degree() const
    232     {
    233         return 0;
    234     }
    235     int count() const
    236     {
    237         return count(root());
    238     }
    239 
    240     int height() const
    241     {
    242         return 0;
    243     }
    244 
    245     void clear()
    246     {
    247         free(root());
    248 
    249         this->m_root = NULL;
    250     }
    251 
    252     ~GTree()
    253     {
    254         clear();
    255     }
    256 };
    257 
    258 }
    259 
    260 #endif // GTREE_H

    测试程序如下:

     1 #include <iostream>
     2 #include "GTree.h"
     3 #include "GTreeNode.h"
     4 
     5 
     6 using namespace std;
     7 using namespace DTLib;
     8 
     9 
    10 int main()
    11 {
    12     GTree<char> t;
    13     GTreeNode<char>* node = NULL;
    14     GTreeNode<char> root;
    15 
    16     root.value = 'A';
    17     root.parent = NULL;
    18 
    19     t.insert(&root);
    20 
    21     node = t.find('A');
    22     t.insert('B', node);
    23     t.insert('C', node);
    24     t.insert('D', node);
    25 
    26     node = t.find('B');
    27     t.insert('E', node);
    28     t.insert('F', node);
    29 
    30     node = t.find('E');
    31     t.insert('K', node);
    32     t.insert('L', node);
    33 
    34     node = t.find('C');
    35     t.insert('G', node);
    36 
    37     node = t.find('D');
    38     t.insert('H', node);
    39     t.insert('I', node);
    40     t.insert('J', node);
    41 
    42     node = t.find('H');
    43     t.insert('M', node);
    44 
    45     cout << t.count() << endl;
    46 
    47 
    48     return 0;
    49 }

    结果如下:

    添加求高度和度数的函数:

      1 #ifndef GTREE_H
      2 #define GTREE_H
      3 
      4 #include "Tree.h"
      5 #include "GTreeNode.h"
      6 #include "Exception.h"
      7 
      8 namespace DTLib
      9 {
     10 
     11 template < typename T >
     12 class GTree : public Tree<T>
     13 {
     14 protected:
     15     GTreeNode<T>* find(GTreeNode<T>* node, const T& value) const
     16     {
     17         GTreeNode<T>* ret = NULL;
     18 
     19         if( node != NULL )
     20         {
     21             if( node->value == value )
     22             {
     23                 return node;
     24             }
     25             else
     26             {
     27                 for(node->child.move(0); !node->child.end() && (ret == NULL); node->child.next())
     28                 {
     29                     ret = find(node->child.current(), value);
     30                 }
     31             }
     32         }
     33 
     34         return ret;
     35     }
     36 
     37     GTreeNode<T>* find(GTreeNode<T>* node,  GTreeNode<T>* obj) const
     38     {
     39         GTreeNode<T>* ret = NULL;
     40 
     41         if( node == obj )
     42         {
     43             return node;
     44         }
     45         else
     46         {
     47             if( node != NULL )
     48             {
     49                 for( node->child.move(0); !node->child.end() && (ret == NULL); node->child.next())
     50                 {
     51                     ret = find(node->child.current(), obj);
     52                 }
     53             }
     54         }
     55 
     56         return ret;
     57     }
     58 
     59     void free(GTreeNode<T>* node)
     60     {
     61         if( node != NULL )
     62         {
     63             for(node->child.move(0); !node->child.end(); node->child.next())
     64             {
     65                 free(node->child.current());
     66             }
     67 
     68             if( node->flag() )
     69             {
     70                 delete node;
     71             }
     72         }
     73     }
     74 
     75     void remove(GTreeNode<T>* node, GTree<T>*& ret)
     76     {
     77         ret = new GTree<T>();
     78 
     79         if( ret == NULL )
     80         {
     81             THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create tree...");
     82         }
     83         else
     84         {
     85             if( root() == node )
     86             {
     87                 this->m_root = NULL;
     88             }
     89             else
     90             {
     91                 LinkList<GTreeNode<T>*>& child = dynamic_cast<GTreeNode<T>*>(node->parent)->child;
     92 
     93                 child.remove(child.find(node));
     94 
     95                 node->parent = NULL;
     96             }
     97 
     98             ret->m_root = node;
     99         }
    100     }
    101 
    102     int count(GTreeNode<T>* node) const
    103     {
    104         int ret = 0;
    105 
    106         if( node != NULL )
    107         {
    108             ret = 1;
    109 
    110             //node如果没有孩子,则for不执行
    111             for(node->child.move(0); !node->child.end(); node->child.next())
    112             {
    113                 ret += count(node->child.current());
    114             }
    115         }
    116 
    117         return ret;
    118     }
    119 
    120     int height(GTreeNode<T>* node) const
    121     {
    122         int ret = 0;
    123 
    124         if( node != NULL )
    125         {
    126             for(node->child.move(0); !node->child.end(); node->child.next())
    127             {
    128                 int h = height(node->child.current());
    129 
    130                 if( ret < h )
    131                 {
    132                     ret = h;
    133                 }
    134             }
    135 
    136             ret = ret + 1;
    137         }
    138 
    139         return ret;
    140     }
    141 
    142     int degree(GTreeNode<T>* node) const
    143     {
    144         int ret = 0;
    145 
    146         if( node != NULL )
    147         {
    148             ret = node->child.length();  //根节点的度数
    149 
    150             for(node->child.move(0); !node->child.end(); node->child.next())
    151             {
    152                 int d = degree(node->child.current());
    153 
    154                 if( ret < d )
    155                 {
    156                     ret = d;
    157                 }
    158             }
    159         }
    160 
    161         return ret;
    162     }
    163 public:
    164     bool insert(TreeNode<T>* node)
    165     {
    166         bool ret = true;
    167 
    168         if( node != NULL )
    169         {
    170             if( this->m_root == NULL ) //如果待插入节点的父节点为空,则这个节点将为根节点
    171             {
    172                 node->parent = NULL;
    173                 this->m_root = node;
    174             }
    175             else
    176             {
    177                 GTreeNode<T>* np = find(node->parent);
    178 
    179                 if( np != NULL )
    180                 {
    181                     GTreeNode<T>* n = dynamic_cast<GTreeNode<T>*>(node);
    182 
    183                     if( np->child.find(n) < 0 )
    184                     {
    185                         np->child.insert(n);
    186                     }
    187                 }
    188                 else
    189                 {
    190                     THROW_EXCEPTION(InvalidParameterException, "Invalid parent tree node...");
    191                 }
    192             }
    193         }
    194         else
    195         {
    196             THROW_EXCEPTION(InvalidParameterException, "Parameter node cannot be NULL ...");
    197         }
    198 
    199         return ret;
    200     }
    201 
    202     bool insert(const T& value, TreeNode<T>* parent)
    203     {
    204         bool ret = true;
    205 
    206         GTreeNode<T>* node = GTreeNode<T>::NewNode();
    207 
    208         if( node != NULL )
    209         {
    210             node->value = value;
    211             node->parent = parent;
    212 
    213             insert(node);
    214         }
    215         else
    216         {
    217             THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create node ...");
    218         }
    219 
    220         return ret;
    221     }
    222 
    223     //删除的节点的子节点我们还需要处理,因此要返回删除节点的指针,这样有机会对里面的元素做进一步操作
    224     SharedPointer< Tree<T> > remove(const T& value)
    225     {
    226         GTree<T>* ret = NULL;
    227 
    228         GTreeNode<T>* node = find(value);
    229 
    230         if( node == NULL )
    231         {
    232             THROW_EXCEPTION(InvalidParameterException, "can not find the node ...");
    233         }
    234         else
    235         {
    236             remove(node, ret);
    237         }
    238 
    239         return ret;
    240     }
    241 
    242     SharedPointer< Tree<T> > remove(TreeNode<T>* node)
    243     {
    244         GTree<T>* ret = NULL;
    245 
    246         node = find(node);
    247 
    248         if( node == NULL )
    249         {
    250             THROW_EXCEPTION(InvalidParameterException, "parameter node is invalid ...");
    251         }
    252         else
    253         {
    254             remove(dynamic_cast<GTreeNode<T>*>(node), ret);
    255         }
    256 
    257         return ret;
    258     }
    259 
    260     GTreeNode<T>* find(const T& value) const  // 返回GTreeNode,赋值兼容性
    261     {
    262         return find(root(), value);
    263     }
    264 
    265     GTreeNode<T>* find(TreeNode<T>* node) const
    266     {
    267         return find(root(), dynamic_cast<GTreeNode<T>*>(node));
    268     }
    269 
    270     GTreeNode<T>* root() const
    271     {
    272         return dynamic_cast<GTreeNode<T>*>(this->m_root);
    273     }
    274 
    275     int degree() const
    276     {
    277         return degree(root());
    278     }
    279     int count() const
    280     {
    281         return count(root());
    282     }
    283 
    284     int height() const
    285     {
    286         return height(root());
    287     }
    288 
    289     void clear()
    290     {
    291         free(root());
    292 
    293         this->m_root = NULL;
    294     }
    295 
    296     ~GTree()
    297     {
    298         clear();
    299     }
    300 };
    301 
    302 }
    303 
    304 #endif // GTREE_H

  • 相关阅读:
    加了一句话
    由于数据库 'XXX' 离线,无法打开该数据库。
    Linux命令list
    js 数组去重
    JSON.parse(JSON.stringify()) 实现对对象的深度拷贝,从而互不影响
    docker
    Node child_process Study.2
    node assert模块 Study.1
    git 合并本地分支到远程分支
    Vue 项目搭建
  • 原文地址:https://www.cnblogs.com/wanmeishenghuo/p/9692420.html
Copyright © 2020-2023  润新知