节点的度:书中某一节点拥有的子节点数量。

数的度:该树中所有节点的度的最大值。

叶节点(终端节点):度为零的节点。

分支节点(非终端节点):度不为零的节点。

根节点(开始节点):树中的第一个节点。

内部节点:树中除了根节点之外的节点。

节点的层数:若根节点层数为1,根节点的第n代子节点的层数为n。

树的高度:书中的节点的最大层数。

有序树和无序树:若树中某一节点的子节点无序,则该树为无序树,否则为有序树。

森林:去掉一棵树的根节点后得到的n棵树。

1.树是一种很基础很重要的非线性结构。

2.除表头(树根)和表尾(叶节点)外,任何一个节点只有一个直接前驱,但有多个直接后继。

3.树是数据的有限集,树分为空树和非空树。 

  非空树:有且只有一个根节点。若根节点的子节点大于1,可以理解为这棵非空树有m棵相互独立的非空树组成。

4.树的递归特性(★★★):一颗非空树有若干子树组成,每一棵子树又由更小的子组成。


 

C++实现:

[MyTree.h]:无序树类模板头文件

  1. #pragma once
  2. template<class T>
  3. class MyTree
  4. {
  5. private:
  6. struct TreeNode //定义私有,不让用户使用
  7. {
  8. T data; //数据域,可以多个数据
  9. //指针域
  10. TreeNode *parent; //节点的父指针
  11. TreeNode *child; //子指针
  12. TreeNode *brother; //兄弟指针 兄弟之间逐级管理
  13. };
  14. TreeNode *pRoot; //根节点
  15. public:
  16. MyTree();
  17. ~MyTree();
  18. void clear();
  19. void insertNode(const T& parentData, const T& insertData, bool insertChild = true); //默认插入为子节点
  20. //bool isFind(const T& findData);
  21. void preOrderPrint(TreeNode *root /*= pRoot*/); //前序(前根)遍历
  22. void posOrderPrint(TreeNode *root /*= pRoot*/); //前序(后根)遍历
  23. void inOrderPrint(TreeNode *root /*= pRoot*/); //中序(中根)遍历
  24. TreeNode* getTreeRoot();
  25. private:
  26. void _clear(TreeNode *root); //用于clear()函数的实现,不提供接口
  27. TreeNode* _find(TreeNode *root, const T& findData);
  28. };
  29. template<class T>
  30. typename MyTree<T>::TreeNode* MyTree<T>::getTreeRoot()
  31. {
  32. return pRoot;
  33. }
  34. template<class T>
  35. void MyTree<T>::inOrderPrint(TreeNode *root /*= pRoot*/)
  36. {
  37. if (!root)
  38. return;
  39. inOrderPrint(root->child);
  40. std::cout << root->data << " ";
  41. inOrderPrint(root->brother);
  42. }
  43. template<class T>
  44. void MyTree<T>::posOrderPrint(TreeNode *root /*= pRoot*/)
  45. {
  46. if (!root)
  47. return;
  48. posOrderPrint(root->child);
  49. posOrderPrint(root->brother);
  50. std::cout << root->data << " ";
  51. }
  52. template<class T>
  53. void MyTree<T>::preOrderPrint(TreeNode *root /*= pRoot*/)
  54. {
  55. if (!root)
  56. return;
  57. std::cout << root->data << " ";
  58. preOrderPrint(root->child);
  59. preOrderPrint(root->brother);
  60. }
  61. template<class T>
  62. void MyTree<T>::insertNode(const T& parentData, const T& insertData, bool insertChild /*= true*/)
  63. {
  64. TreeNode *tempInsertNode = new TreeNode; //生成一个待插入的节点
  65. tempInsertNode->data = insertData;
  66. tempInsertNode->parent = NULL;
  67. tempInsertNode->child = NULL;
  68. tempInsertNode->brother = NULL;
  69. if (pRoot) //判断树是否为空
  70. {
  71. TreeNode *findNode = _find(pRoot, parentData); //找到插入位置
  72. if (findNode)
  73. {//找到了插入位置
  74. if (insertChild)
  75. {//在子节点插入
  76. TreeNode *temp = findNode->child;
  77. if (temp)
  78. {
  79. while (temp->brother)
  80. temp = temp->brother;
  81. temp->brother = tempInsertNode;
  82. tempInsertNode->parent = findNode;
  83. }
  84. else
  85. {
  86. findNode->child = tempInsertNode;
  87. tempInsertNode->parent = findNode;
  88. }
  89. }
  90. else
  91. {//在兄弟节点插入
  92. if (findNode->brother)
  93. {
  94. TreeNode *tempNode = findNode->brother;
  95. while (tempNode->brother)
  96. tempNode = tempNode->brother;
  97. tempNode->brother = tempInsertNode;
  98. tempInsertNode->parent = tempNode->parent;
  99. }
  100. else
  101. {
  102. //没有兄弟节点
  103. findNode->brother = tempInsertNode;
  104. tempInsertNode->parent = findNode->parent;
  105. }
  106. }
  107. }
  108. else
  109. {//如果没有找到插入位置 设计为插入在末尾
  110. std::cout << "can not find the parent,insert the data in the end" << std::endl;
  111. TreeNode *temp = pRoot;
  112. while (temp->child)
  113. temp = temp->child;
  114. temp->child = tempInsertNode;
  115. tempInsertNode->parent = temp;
  116. }
  117. }
  118. else
  119. {//树为空的情况
  120. // TreeNode *temp = new TreeNode;
  121. // temp->data = insertData;
  122. // temp->parent = NULL;
  123. // inNode->child = inNode->brother = NULL;
  124. pRoot = tempInsertNode;
  125. }
  126. }
  127. template<class T>
  128. typename MyTree<T>::TreeNode * MyTree<T>::_find(TreeNode *root, const T& findData)
  129. {
  130. if (root) /*递归结束条件 传入的的指针为空 例如判断叶节点是 将叶子节点的子节点传入递归函数,
  131. 不满足条件直接返回空*/
  132. {
  133. //先判断本节点 在判断子节点 最后判断兄弟节点 找到直接返回 不继续找
  134. if (root->data == findData) //判断当前节点是否为 需要找的节点
  135. return root;
  136. TreeNode * temp = _find(root->child, findData);
  137. if (temp)
  138. return temp;
  139. if (temp = _find(root->brother, findData))
  140. return temp;
  141. }
  142. return NULL; //若没有找到 返回为空
  143. }
  144. template<class T>
  145. void MyTree<T>::_clear(TreeNode *root)
  146. {
  147. //用递归删除所有节点 树的递归特性
  148. if (root)
  149. {
  150. _clear(root->child);
  151. _clear(root->brother); //先删除兄弟和先删除儿子一样
  152. delete[]root; //必须先删除兄弟和儿子后才能删除自己
  153. root = nullptr; //所有内存被释放后 指针置空
  154. }
  155. }
  156. template<class T>
  157. void MyTree<T>::clear()
  158. {
  159. _clear(pRoot); //不需要再进行判空 ,_clear()中会判断
  160. }
  161. template<class T>
  162. MyTree<T>::~MyTree()
  163. {
  164. clear();
  165. }
  166. template<class T>
  167. MyTree<T>::MyTree()
  168. {
  169. pRoot = nullptr;
  170. }

代码测试:

 

  1. // 无序树.cpp : 定义控制台应用程序的入口点。
  2. //
  3. #include "stdafx.h"
  4. #include "MyTree.h"
  5. #include<iostream>
  6. using namespace std;
  7. int _tmain(int argc, _TCHAR* argv[])
  8. {
  9. MyTree<int> tree;
  10. std::cout << "tree:" << endl;;
  11. tree.insertNode(1, 1);
  12. cout << 1 << '\n' << '|' << endl;;
  13. tree.insertNode(1, 2, 1);
  14. tree.insertNode(2, 5, 0);
  15. tree.insertNode(2, 9, 0);
  16. cout << 2 << "" << 5<<"— —"<<9<<endl;
  17. cout << '|' << " " << "|" <<" "<<"|"<< endl;
  18. tree.insertNode(2, 3, 1);
  19. tree.insertNode(5, 6, 1);
  20. tree.insertNode(6, 7, 0);
  21. tree.insertNode(9, 10, 1);
  22. cout << 3 << " " << 6 << "" << 7 <<" "<< 10 << endl;
  23. cout << "|" << " " << "|" << endl;
  24. tree.insertNode(3, 4, 1);
  25. tree.insertNode(7, 8, 1);
  26. cout << 4 << " " << 8 << "\n\n"<<endl;
  27. std::cout << "前序遍历:";
  28. tree.preOrderPrint(tree.getTreeRoot());
  29. std::cout << std::endl;
  30. std::cout << "后序遍历:";
  31. tree.posOrderPrint(tree.getTreeRoot());
  32. std::cout << std::endl;
  33. std::cout << "中序遍历:";
  34. tree.inOrderPrint(tree.getTreeRoot());
  35. std::cout << std::endl;
  36. std::cin.get();
  37. return 0;
  38. }

 

测试结果:

 

 

 

版权声明:本文为daniumeng原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/daniumeng/p/8597862.html