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

问题:

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

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

 

插入操作代码流程:

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

 在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 }

结果如下:

小结:

猜你喜欢

转载自www.cnblogs.com/wanmeishenghuo/p/9690961.html