当前位置:   article > 正文

C++实现二叉树的创建及遍历_c++二叉树的建立与遍历

c++二叉树的建立与遍历

二叉树的结点类

  1. class Node
  2. {
  3. public:
  4. Node() = default;
  5. Node(int data) : _data(data), _lchild(nullptr), _rchild(nullptr) {};
  6. public:
  7. char _data; // 数据域以 char 型为例,严谨点可写成模板
  8. Node* _lchild; // 指向左孩的指针(左右孩也是一个Node)
  9. Node* _rchild; // 指向右孩
  10. };

二叉树的建立

  1. // 递归建立二叉树,但是这个建完了 T 就不指向根节点了,暂未解决 // 已解决,void CreatBT(Node* T) ---> void CreatBT(Node* &t); 但是为什么这样可行还需要思考一下!!!
  2. // 这里用引用传递的方式,目的是保留原有的根节点指针指向不受影响
  3. void CreatBT(Node* &root)
  4. {
  5. char ch;
  6. cout << "请输入结点中存放的数据:";
  7. cin >> ch;
  8. if(ch == '#')
  9. {
  10. root = nullptr;
  11. }
  12. else
  13. {
  14. root = new(Node);
  15. root->_data = ch;
  16. CreatBT(root->_lchild);
  17. CreatBT(root->_rchild);
  18. }
  19. }

先序遍历二叉树

  1. // 先序遍历二叉树
  2. void preOrderTraverse(Node* root)
  3. {
  4. if(root == nullptr) {}
  5. else
  6. {
  7. cout << root->_data << " ";
  8. preOrderTraverse(root->_lchild); //递归
  9. preOrderTraverse(root->_rchild);
  10. }
  11. }

中序遍历二叉树

  1. // 中序遍历二叉树
  2. void inOrderTraverse(Node* root)
  3. {
  4. if(root == nullptr) {}
  5. else
  6. {
  7. inOrderTraverse(root->_lchild);
  8. cout << root->_data << " ";
  9. inOrderTraverse(root->_rchild);
  10. }
  11. }

后序遍历二叉树

  1. // 后序遍历二叉树
  2. void postOrderTraverse(Node* root)
  3. {
  4. if(root == nullptr) {}
  5. else
  6. {
  7. postOrderTraverse(root->_lchild);
  8. postOrderTraverse(root->_rchild);
  9. cout << root->_data << " ";
  10. }
  11. }

中序遍历的非递归算法

  1. // 中序遍历的非递归算法
  2. void inOrdrtTraverse_norecursion(Node* root)
  3. {
  4. Node* p = root;
  5. stack<Node*> s; // 使用一个栈,保存每个小二叉树的根节点
  6. while(p != nullptr || !s.empty())
  7. {
  8. if(p != nullptr)
  9. {
  10. s.push(p);
  11. p = p->_lchild;
  12. }
  13. else
  14. {
  15. Node* q = s.top();
  16. s.pop();
  17. cout << q->_data << " ";
  18. p = q->_rchild;
  19. }
  20. }
  21. }

二叉树的层次遍历

  1. // 二叉树的层次遍历
  2. void LevelOrder(Node* root)
  3. {
  4. Node* p;
  5. queue<Node*> q; // 使用一个队列,根节点入队
  6. q.push(root);
  7. while(!q.empty())
  8. {
  9. p = q.front();
  10. cout << p->_data << " ";
  11. q.pop();
  12. if(p->_lchild != nullptr)
  13. {
  14. q.push(p->_lchild);
  15. }
  16. if(p->_rchild != nullptr)
  17. {
  18. q.push(p->_rchild);
  19. }
  20. }
  21. }

计算二叉树的深度

  1. // 计算二叉树的深度
  2. int Depth(Node* T)
  3. {
  4. if(T == nullptr)
  5. {
  6. return 0;
  7. }
  8. else
  9. {
  10. int m = Depth(T->_lchild);
  11. int n = Depth(T->_rchild);
  12. return (m > n) ? (m + 1) : (n + 1);
  13. }
  14. }

计算二叉树的总结点数

  1. // 计算二叉树结点总数
  2. int NodeCount(Node* T)
  3. {
  4. if(T == nullptr)
  5. {
  6. return 0;
  7. }
  8. else
  9. {
  10. return NodeCount(T->_lchild) + NodeCount(T->_rchild) + 1;
  11. }
  12. }

计算二叉树叶子节点数

  1. // 计算二叉树叶子节点数
  2. int leafNodeCount(Node* T)
  3. {
  4. if(T == nullptr)
  5. {
  6. return 0;
  7. }
  8. if(T->_lchild == nullptr && T->_rchild == nullptr)
  9. {
  10. return 1;
  11. }
  12. else
  13. {
  14. return leafNodeCount(T->_lchild) + leafNodeCount(T->_rchild);
  15. }
  16. }

测试

构建如下测试用例二叉树,并依次测试所写的每一个函数。

按照二叉树的建立函数中的思路,将其以 ‘#’ 补齐为满二叉树,如下 :

 

其先序遍历为:ABC##DE#G##F###,我们按照这个顺序建立二叉树,并进行测试,结果如下:

 完整代码

  1. #include <iostream>
  2. #include <stack>
  3. #include <queue>
  4. #include <string>
  5. using namespace std;
  6. // 二叉链树的创建和遍历
  7. class Node
  8. {
  9. public:
  10. Node() = default;
  11. Node(int data) : _data(data), _lchild(nullptr), _rchild(nullptr) {};
  12. public:
  13. char _data; // 数据域以 char 型为例,严谨点可写成模板
  14. Node* _lchild; // 指向左孩的指针(左右孩也是一个Node)
  15. Node* _rchild; // 指向右孩
  16. };
  17. // 递归建立二叉树,但是这个建完了 T 就不指向根节点了,暂未解决 // 已解决,void CreatBT(Node* T) ---> void CreatBT(Node* &t); 但是为什么这样可行还需要思考一下!!!
  18. // 这里用引用传递的方式,目的是保留原有的根节点指针指向不受影响
  19. void CreatBT(Node* &root)
  20. {
  21. char ch;
  22. cout << "请输入结点中存放的数据:";
  23. cin >> ch;
  24. if(ch == '#')
  25. {
  26. root = nullptr;
  27. }
  28. else
  29. {
  30. root = new(Node);
  31. root->_data = ch;
  32. CreatBT(root->_lchild);
  33. CreatBT(root->_rchild);
  34. }
  35. }
  36. // 先序遍历二叉树
  37. void preOrderTraverse(Node* root)
  38. {
  39. if(root == nullptr) {}
  40. else
  41. {
  42. cout << root->_data << " ";
  43. preOrderTraverse(root->_lchild); //递归
  44. preOrderTraverse(root->_rchild);
  45. }
  46. }
  47. // 中序遍历二叉树
  48. void inOrderTraverse(Node* root)
  49. {
  50. if(root == nullptr) {}
  51. else
  52. {
  53. inOrderTraverse(root->_lchild);
  54. cout << root->_data << " ";
  55. inOrderTraverse(root->_rchild);
  56. }
  57. }
  58. // 后序遍历二叉树
  59. void postOrderTraverse(Node* root)
  60. {
  61. if(root == nullptr) {}
  62. else
  63. {
  64. postOrderTraverse(root->_lchild);
  65. postOrderTraverse(root->_rchild);
  66. cout << root->_data << " ";
  67. }
  68. }
  69. // 中序遍历的非递归算法
  70. void inOrdrtTraverse_norecursion(Node* root)
  71. {
  72. Node* p = root;
  73. stack<Node*> s; // 使用一个栈,保存每个小二叉树的根节点
  74. while(p != nullptr || !s.empty())
  75. {
  76. if(p != nullptr)
  77. {
  78. s.push(p);
  79. p = p->_lchild;
  80. }
  81. else
  82. {
  83. Node* q = s.top();
  84. s.pop();
  85. cout << q->_data << " ";
  86. p = q->_rchild;
  87. }
  88. }
  89. }
  90. // 二叉树的层次遍历
  91. void LevelOrder(Node* root)
  92. {
  93. Node* p;
  94. queue<Node*> q; // 使用一个队列,根节点入队
  95. q.push(root);
  96. while(!q.empty())
  97. {
  98. p = q.front();
  99. cout << p->_data << " ";
  100. q.pop();
  101. if(p->_lchild != nullptr)
  102. {
  103. q.push(p->_lchild);
  104. }
  105. if(p->_rchild != nullptr)
  106. {
  107. q.push(p->_rchild);
  108. }
  109. }
  110. }
  111. // 计算二叉树的深度
  112. int Depth(Node* T)
  113. {
  114. if(T == nullptr)
  115. {
  116. return 0;
  117. }
  118. else
  119. {
  120. int m = Depth(T->_lchild);
  121. int n = Depth(T->_rchild);
  122. return (m > n) ? (m + 1) : (n + 1);
  123. }
  124. }
  125. // 计算二叉树结点总数
  126. int NodeCount(Node* T)
  127. {
  128. if(T == nullptr)
  129. {
  130. return 0;
  131. }
  132. else
  133. {
  134. return NodeCount(T->_lchild) + NodeCount(T->_rchild) + 1;
  135. }
  136. }
  137. // 计算二叉树叶子节点数
  138. int leafNodeCount(Node* T)
  139. {
  140. if(T == nullptr)
  141. {
  142. return 0;
  143. }
  144. if(T->_lchild == nullptr && T->_rchild == nullptr)
  145. {
  146. return 1;
  147. }
  148. else
  149. {
  150. return leafNodeCount(T->_lchild) + leafNodeCount(T->_rchild);
  151. }
  152. }
  153. void test01()
  154. {
  155. Node* T = nullptr;
  156. CreatBT(T);
  157. cout << "该二叉树先序遍历结果为:";
  158. preOrderTraverse(T);
  159. cout << endl << endl;
  160. cout << "该二叉树中序递归遍历结果为:";
  161. inOrderTraverse(T);
  162. cout << endl << endl;
  163. cout << "该二叉树中序非递归遍历结果为:";
  164. inOrdrtTraverse_norecursion(T);
  165. cout << endl << endl;
  166. cout << "该二叉树后序遍历结果为:";
  167. postOrderTraverse(T);
  168. cout << endl << endl;
  169. cout << "该二叉树层次遍历结果为:";
  170. LevelOrder(T);
  171. cout << endl << endl;
  172. cout << "该二叉树的深度为:" << Depth(T) << endl << endl;
  173. cout << "该二叉树的结点数为:" << NodeCount(T) << endl << endl;
  174. cout << "该二叉树的叶子结点数为:" << leafNodeCount(T) << endl << endl;
  175. }
  176. int main()
  177. {
  178. test01();
  179. system("pause");
  180. return 0;
  181. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/557746
推荐阅读
相关标签
  

闽ICP备14008679号