问题:
新插入节点的位置如何指定?
非线性结构无法通过下标指定位置。
插入操作代码流程:
当前的树是一棵空树的话,新节点就当做空节点来插入。不是空树就查找新节点的父节点。
在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 }
结果如下:
小结: