GTree.h 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474
  1. #ifndef GTREE_H
  2. #define GTREE_H
  3. #include <vector>
  4. #include <map>
  5. #include <iostream>
  6. using namespace std;
  7. enum GTreeNodeType
  8. {
  9. Product,
  10. Part
  11. };
  12. // 通用树节点
  13. template < typename T >
  14. class GTreeNode
  15. {
  16. public:
  17. T value;
  18. GTreeNode<T>* parent;
  19. vector<GTreeNode<T>*> child;
  20. bool m_flag;
  21. GTreeNode()
  22. {
  23. parent = NULL;
  24. m_flag = false;
  25. }
  26. static GTreeNode<T>* NewNode() // 工厂模式
  27. {
  28. GTreeNode<T>* ret = new GTreeNode<T>();
  29. if (ret != NULL) // 申请堆空间成功
  30. {
  31. ret->m_flag = true;
  32. }
  33. return ret;
  34. }
  35. bool add(GTreeNode<T>* node)
  36. {
  37. child.push_back(node);
  38. }
  39. bool flag()
  40. {
  41. return m_flag;
  42. }
  43. };
  44. template <typename T>
  45. class GTree
  46. {
  47. public:
  48. GTreeNode<T>* m_root;
  49. string name;
  50. GTree() { m_root = GTreeNode<T>::NewNode(); }
  51. //插入结点
  52. GTreeNode<T>* GetRootNode() { return m_root; }
  53. string GetName()
  54. {
  55. return name;
  56. }
  57. void SetName(string _name)
  58. {
  59. name = _name;
  60. }
  61. //基于数据元素值的查找,都是遍历实现的
  62. GTreeNode<T>* find(GTreeNode<T>* node, const T& value)const
  63. {
  64. GTreeNode<T>* ret = NULL;
  65. if (node != NULL)
  66. {
  67. //如果根结点的就是目标结点
  68. if (node->value == value)
  69. {
  70. return node;
  71. }
  72. else
  73. {
  74. //遍历根节点的子结点
  75. //for (node->child.move(0); !node->child.end() && (ret == NULL); node->child.next())
  76. //{
  77. // //对每个子子结点进行查找
  78. // ret = find(node->child.current(), value);
  79. //}
  80. for (int i = 0; i < node->child.size(); i++)
  81. {
  82. //对每个子子结点进行查找
  83. ret = find(node->child[i], value);
  84. }
  85. }
  86. }
  87. return ret;
  88. }
  89. //基于结点得查找
  90. GTreeNode<T>* find(GTreeNode<T>* node, GTreeNode<T>* obj)const
  91. {
  92. GTreeNode<T>* ret = NULL;
  93. //根结点为目标结点
  94. if (node == obj)
  95. {
  96. return node;
  97. }
  98. else
  99. {
  100. if (node != NULL)
  101. {
  102. //遍历子结点
  103. //for (node->child.move(0); !node->child.end() && (ret == NULL); node->child.next())
  104. //{
  105. // ret = find(node->child.current(), obj);
  106. //}
  107. for (int i = 0; i < node->child.size(); i++)
  108. {
  109. ret = find(node->child[i], obj);
  110. }
  111. }
  112. }
  113. return ret;
  114. }
  115. void free(GTreeNode<T>* node)
  116. {
  117. if (node != NULL)
  118. {
  119. //for (node->child.move(0); !node->child.end(); node->child.next())
  120. //{
  121. // free(node->child.current());
  122. //}
  123. for (int i = 0; i < node->child.size(); i++)
  124. {
  125. free(node->child[i]);
  126. }
  127. if (node->flag())
  128. {
  129. delete node;
  130. }
  131. }
  132. }
  133. /*
  134. * 删除操作成员函数的设计要点
  135. * 将被删除结点所代表的子树进行删除
  136. * 删除函数返回一颗堆空间中的树
  137. * 具体返回值为指向树的智能指针对象
  138. */
  139. void remove(GTreeNode<T>* node, GTree<T>*& ret)
  140. {
  141. ret = new GTree<T>();
  142. if (ret == NULL)
  143. {
  144. //THROW_EXCEPTION(NoEoughMemoryException, "...");
  145. }
  146. else
  147. {
  148. if (root() != node)
  149. {
  150. //获取删除结点的父结点的子结点链表
  151. //LinkList<GTreeNode<T>*>& child = dynamic_cast<GTreeNode<T>*>(node->parent)->child;
  152. child.remove(child.find(node)); //从链表中删除结点
  153. node->parent = NULL;//结点的父结点置NULL
  154. }
  155. else
  156. {
  157. this->m_root = NULL;
  158. }
  159. }
  160. }
  161. int count(GTreeNode<T>* node)const
  162. {
  163. int ret = 0;
  164. if (node != NULL)
  165. {
  166. ret = 1;
  167. //遍历根结点的子节点
  168. for (node->child.move(0); !node->child.end(); node->child.next())
  169. {
  170. ret += count(node->child.current());//对结点进行统计
  171. }
  172. }
  173. return ret;
  174. }
  175. int degree(GTreeNode<T>* node)const
  176. {
  177. int ret = 0;
  178. if (node != NULL)
  179. {
  180. ret = node->child.length();
  181. for (node->child.move(0); !node->child.end(); node->child.next())
  182. {
  183. int d = degree(node->child.current());
  184. if (ret < d)
  185. {
  186. ret = d;
  187. }
  188. }
  189. }
  190. return ret;
  191. }
  192. int height(GTreeNode<T>* node)const
  193. {
  194. int ret = 0;
  195. if (node != NULL)
  196. {
  197. for (node->child.move(0); !node->child.end(); node->child.next())
  198. {
  199. int h = height(node->child.current());
  200. if (ret < h)
  201. {
  202. ret = h;
  203. }
  204. }
  205. ret = ret + 1;
  206. }
  207. return ret;
  208. }
  209. bool insert(GTreeNode<T>* node)
  210. {
  211. bool ret = true;
  212. if (node != NULL)//当结点不为空时
  213. {
  214. if (this->m_root == NULL)//如果此时的根结点为空
  215. {
  216. node->parent = NULL;//node结点就是根结点
  217. this->m_root = node;
  218. }
  219. else
  220. {
  221. GTreeNode<T>* np = find(node->parent);//在堆空间创建np指向node的父节点
  222. if (np != NULL)
  223. {
  224. GTreeNode<T>* n = dynamic_cast<GTreeNode<T>*>(node);//noded的类型为TreeNode,需要将其强制转换为GTreeNode
  225. //if (np->child.find(n) < 0)
  226. //{
  227. // ret = np->child.insert(n);
  228. //}
  229. np->child.push_back(n);
  230. }
  231. else
  232. {
  233. //THROW_EXCEPTION(InvalidOperationException, "...");
  234. }
  235. }
  236. }
  237. else
  238. {
  239. //THROW_EXCEPTION(InvalidOperationException, "...");
  240. }
  241. return ret;
  242. }
  243. bool insert(const T& value, GTreeNode<T>* parent)
  244. {
  245. bool ret = true;
  246. GTreeNode<T>* node = GTreeNode<T>::NewNode();
  247. if (node != NULL)
  248. {
  249. node->value = value;
  250. node->parent = parent;
  251. insert(node);
  252. }
  253. else
  254. {
  255. //THROW_EXCEPTION(InvalidOperationException, "...");
  256. }
  257. return ret;
  258. }
  259. bool change(const T& value, GTreeNode<T>* node)
  260. {
  261. bool ret = true;
  262. if (node != NULL)
  263. {
  264. node->value = value;
  265. }
  266. else
  267. {
  268. //THROW_EXCEPTION(InvalidOperationException, "...");
  269. }
  270. return ret;
  271. }
  272. GTreeNode<T>* add(const T& value, GTreeNode<T>* parent)
  273. {
  274. GTreeNode<T>* node = GTreeNode<T>::NewNode();
  275. if (node != NULL)
  276. {
  277. node->value = value;
  278. node->parent = parent;
  279. insert(node);
  280. }
  281. else
  282. {
  283. //THROW_EXCEPTION(InvalidOperationException, "...");
  284. }
  285. return node;
  286. }
  287. //删除结点
  288. //SharedPointer< Tree<T> > remove(const T& value)
  289. //{
  290. // GTree<T>* ret = NULL;
  291. // GTreeNode<T>* node = find(value);
  292. // if (node != NULL)
  293. // {
  294. // remove(node, ret);
  295. // }
  296. // else
  297. // {
  298. // THROW_EXCEPTION(InvalidOperationException, "...");
  299. // }
  300. // return ret;
  301. //}
  302. //SharedPointer< Tree<T> > remove(TreeNode<T>* node)
  303. //{
  304. // GTree<T>* ret = NULL;
  305. // node = find(node);
  306. // if (node != NULL)
  307. // {
  308. // remove(dynamic_cast<GTreeNode<T>*>(node), ret);
  309. // }
  310. // else
  311. // {
  312. // THROW_EXCEPTION(InvalidOperationException, "...");
  313. // }
  314. // return NULL;
  315. //}
  316. //查找结点
  317. GTreeNode<T>* find(const T& value)const
  318. {
  319. return find(root(), value);
  320. }
  321. GTreeNode<T>* find(GTreeNode<T>* node)const
  322. {
  323. return find(root(), dynamic_cast<GTreeNode<T>*>(node));//强制类型转换将TreeNode类型转换为GTreeNode类型
  324. }//root对应的root的类型也应该一样
  325. //根结点访问函数
  326. GTreeNode<T>* root()const
  327. {
  328. return dynamic_cast<GTreeNode<T>*>(this->m_root);
  329. }
  330. //树的度访问函数
  331. int degree()const
  332. {
  333. return degree(root());
  334. }
  335. //树的高度访问函数
  336. int height()const
  337. {
  338. return height(root());
  339. }
  340. //树的结点数目访问函数
  341. int count()const
  342. {
  343. return count(root());
  344. }
  345. //清空树
  346. void clear()
  347. {
  348. free(root());
  349. this->m_root = NULL;
  350. }
  351. //树中结点的遍历
  352. //树是一种非线性的数据结构,遍历树中结点可以采用游标的方式。
  353. //A、在树中定义一个游标(GTreeNode<T>* node)
  354. //B、遍历开始前将游标指向根结点
  355. //C、获取游标指向的数据元素
  356. //D、通过结点中的child成员移动游标
  357. //bool begin()
  358. //{
  359. // bool ret = (root() != NULL);
  360. // if (ret)
  361. // {
  362. // m_queue.clear();//清空队列
  363. // m_queue.add(root());//将根结点加入队列
  364. // }
  365. // return ret;
  366. //}
  367. //bool end()
  368. //{
  369. // return (m_queue.length() == 0);
  370. //}
  371. //bool next()
  372. //{
  373. // bool ret = (m_queue.length() > 0);
  374. // {
  375. // GTreeNode<T>* node = m_queue.front();
  376. // m_queue.remove();//队头元素出队列
  377. // //将队头元素的子节点入队
  378. // for (node->child.move(0); !node->child.end(); node->child.next())
  379. // {
  380. // m_queue.add(node->child.current());
  381. // }
  382. // return ret;
  383. // }
  384. //}
  385. //T current()
  386. //{
  387. // if (!end())
  388. // {
  389. // return m_queue.front()->value;
  390. // }
  391. // else
  392. // {
  393. // THROW_EXCEPTION(InvalidOperationException, "...");
  394. // }
  395. //}
  396. ~GTree()
  397. {
  398. clear();
  399. }
  400. };
  401. #endif