• 第五十四课 树中节点的插入操作


    问题:

    新插入节点的位置如何指定?

    非线性结构无法通过下标指定位置。

     

    插入操作代码流程:

    当前的树是一棵空树的话,新节点就当做空节点来插入。不是空树就查找新节点的父节点。

     在GTree.h中添加插入操作:

      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 public:
     59     bool insert(TreeNode<T>* node)
     60     {
     61         bool ret = true;
     62 
     63         if( node != NULL )
     64         {
     65             if( this->m_root == NULL ) //如果待插入节点的父节点为空,则这个节点将为根节点
     66             {
     67                 node->parent = NULL;
     68                 this->m_root = node;
     69             }
     70             else
     71             {
     72                 GTreeNode<T>* np = find(node->parent);
     73 
     74                 if( np != NULL )
     75                 {
     76                     GTreeNode<T>* n = dynamic_cast<GTreeNode<T>*>(node);
     77 
     78                     if( np->child.find(n) < 0 )
     79                     {
     80                         np->child.insert(n);
     81                     }
     82                 }
     83                 else
     84                 {
     85                     THROW_EXCEPTION(InvalidParameterException, "Invalid parent tree node...");
     86                 }
     87             }
     88         }
     89         else
     90         {
     91             THROW_EXCEPTION(InvalidParameterException, "Parameter node cannot be NULL ...");
     92         }
     93 
     94         return ret;
     95     }
     96 
     97     bool insert(const T& value, TreeNode<T>* parent)
     98     {
     99         bool ret = true;
    100 
    101         GTreeNode<T>* node = new GTreeNode<T>();
    102 
    103         if( node != NULL )
    104         {
    105             node->value = value;
    106             node->parent = parent;
    107 
    108             insert(node);
    109         }
    110         else
    111         {
    112             THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create node ...");
    113         }
    114 
    115         return ret;
    116     }
    117 
    118     //删除的节点的子节点我们还需要处理,因此要返回删除节点的指针,这样有机会对里面的元素做进一步操作
    119     SharedPointer< Tree<T> > remove(const T& value)
    120     {
    121         return NULL;
    122     }
    123 
    124     SharedPointer< Tree<T> > remove(TreeNode<T>* node)
    125     {
    126         return NULL;
    127     }
    128 
    129     GTreeNode<T>* find(const T& value) const  // 返回GTreeNode,赋值兼容性
    130     {
    131         return find(root(), value);
    132     }
    133 
    134     GTreeNode<T>* find(TreeNode<T>* node) const
    135     {
    136         return find(root(), dynamic_cast<GTreeNode<T>*>(node));
    137     }
    138 
    139     GTreeNode<T>* root() const
    140     {
    141         return dynamic_cast<GTreeNode<T>*>(this->m_root);
    142     }
    143 
    144     int degree() const
    145     {
    146         return 0;
    147     }
    148     int count() const
    149     {
    150         return 0;
    151     }
    152 
    153     int height() const
    154     {
    155         return 0;
    156     }
    157 
    158     void clear()
    159     {
    160         this->m_root = NULL;
    161     }
    162 
    163     ~GTree()
    164     {
    165         clear();
    166     }
    167 };
    168 
    169 }
    170 
    171 #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 
    15     t.insert('A', NULL);
    16 
    17     node = t.find('A');
    18     t.insert('B', node);
    19     t.insert('C', node);
    20     t.insert('D', node);
    21 
    22     node = t.find('B');
    23     t.insert('E', node);
    24     t.insert('F', node);
    25 
    26     node = t.find('E');
    27     t.insert('K', node);
    28     t.insert('L', node);
    29 
    30     node = t.find('C');
    31     t.insert('G', node);
    32 
    33     node = t.find('D');
    34     t.insert('H', node);
    35     t.insert('I', node);
    36     t.insert('J', node);
    37 
    38     node = t.find('H');
    39     t.insert('M', node);
    40 
    41     //用链表来验证我们的插入操作,从下至上遍历
    42 
    43     char* s = "KLFGMIJ";
    44 
    45     for( int i = 0; i < 7; i++ )
    46     {
    47         TreeNode<char>* node = t.find(s[i]);
    48 
    49         while( node != NULL )
    50         {
    51             cout << node->value << " ";
    52 
    53             node = node->parent;
    54         }
    55         cout << endl;
    56     }
    57 
    58 
    59     return 0;
    60 }

    结果如下:

    小结:

  • 相关阅读:
    NotePad++与MinGw的第一次HelloWorld——C语言环境配置说明
    Debian7.5.0安装流程(VirtualBox虚拟机环境)
    NotePad++插件——Customize Toolbar
    NotePad++与MinGw的第一次HelloWorld
    Debian7.5.0安装流程(VirtualBox虚拟机环境)
    stm32f103cbt6 sd卡 移植fatfs 显示在e-ink屏幕上
    stm32f429i disc usb cdc vcp 虚拟串口 example project (CubeMX Hal)
    stm32 cubemx 工程生成报错
    clover 在win10下工作不正常
    proxifier 3.29 key
  • 原文地址:https://www.cnblogs.com/wanmeishenghuo/p/9690961.html
Copyright © 2020-2023  润新知