• 【数据结构】C++二叉树的实现(二叉链表),包括初始化,前序、中序、后序、层次遍历,计算节点数、叶子数、高度、宽度,二叉树的复制和销毁


     *********************************************************************************************************

    本文作者科大MF22某班Noah懒羊羊同学,为大家提供一个作业思路,请勿直接copy!!!一起进步学习~

    **********************************************************************************************************

    目录

    1.问题的描述

    1.1基本功能

    1.2健壮性

    1.3 规范性

    2.算法的描述

    2.1数据结构的描述

    2.2程序结构的描述

    3.调试分析

    4.算法的时空分析

    5.测试结果及分析

    6.实验体会和收获

    代码

    Noah_BiTree.h

     main.cpp


    1.问题的描述

    1.1基本功能

    1、创建二叉树(10’)

    可以使用先序遍历输入,无节点的可以使用#表示。

    例如下图可以输入6423####51##7##。这里前面2个#表示节点3左右孩子节点都为空,第3个#表示节点2右孩子为空,第4个#表示节点4右孩子为空,1和7后面的2个#分别代表节点1和7的左右孩子节点都为空。

    也可以自己选择其他方式输入,但要在readme文件和实验报告说清楚。

    2、遍历二叉树(先序、中序、后序、层序遍历)(20’)

    前序遍历:6423517

    中序遍历:3246157

    后序遍历:3241756

    层序遍历:6452173

    3、二叉树的计算(二叉树的结点数、叶子数、高度、宽度等)(20’)

    结点数:7

    叶子数:3

    高度:4

    宽度:3

    4、 二叉树的处理(复制、销毁)(20’)

    复制要创建一个新的二叉树,对于原二叉树和复制的二叉树之间销毁操作不能互相影响。

    1.2健壮性

    1. 对于创建的二叉树为空的情况,要能程序要能正常运行并识别。(5分)
    2. 对于空树,其他功能要可以识别、输出相应信息,并且程序不能异常终止。(5分)

    1.3 规范性

    1. 代码注释
    2. 程序模块化
    3. 人机交互友好

    2.算法的描述

    2.1数据结构的描述

    程序中应用到的主要数据结构是二叉树(二叉链表)。

    主要变量说明:

    变量

    类型

    说明

    Node、BiTNode

    结构体

    二叉树结点的结构体

    *BiTree

    二叉树结点指针

    二叉树结点的指针

    data

    可变(由宏定义TElemType确定,示例中为char)

    二叉树结点中的数据域

    *lchild

    二叉树结点指针

    结点的左孩子

    *rchild

    二叉树结点指针

    结点的右孩子

    TElemType

    宏定义

    二叉树节点数据域的类型

    2.2程序结构的描述

            程序主要包含Noah_BiTree.h头文件和main.cpp主文件,其中Noah_BiTree.h是二叉链表数据结构的实现代码头文件,N,main.cpp中主要实现菜单和功能界面的交互以及头文件中函数的调用。其具体结构如下图所示。

    3.调试分析

    调试功能一:Create a binary tree and show the tree structure

    创建二叉树并显示树的结构

    测试数据选择:

    1. 6423####51##7##
    2. 124##5##36##7##
    3. #
    4. 1234######

    问题及解决方法:

    调试功能二:Create a binary tree and show show the preoeder, inorder, postorder and levelorder

    创建一个二叉树,显示前序、中序后序和层次遍历。

    测试数据选择:

    1. 6423####51##7##
    2. 124##5##36##7##
    3. 1234######

    问题及解决方法:

    调试功能三:Create a binary tree and calculate the number of nodes, leaves, height and width

    创建一个二叉树,计算节点的数量,叶,高度和宽度

    测试数据选择:

    1. 6423####51##7##
    2. 124##5##36##7##
    3. 1234######

    问题及解决方法:

    调试功能四:Create a binary tree, copy it, destory the original one and show the new tree

    创建一个二叉树,复制它,销毁原来的树,并显示新的树

    测试数据选择:

    1. 6423####51##7##
    2. 124##5##36##7##
    3. 1234######

    问题及解决方法:

    4.算法的时空分析

    (1) CreateBiTree_withhint(BiTree &T)

    时间复杂度:O(n)

    空间复杂度:O(n)

    (2) preorder(BiTree T)

    时间复杂度:O(n)

    空间复杂度:O(n)

    (3) inorder(BiTree T)

    时间复杂度:O(n)

    空间复杂度:O(n)

    (4) postorder(BiTree T)

    时间复杂度:O(n)

    空间复杂度:O(n)

    (5) levelorder(BiTree T)

    时间复杂度:O(n)

    空间复杂度:O(n)

    (6) NumofNode (BiTree T)

    时间复杂度:O(n)

    空间复杂度:O(n)

    (7) BiHight (BiTree T)

    时间复杂度:O(n)

    空间复杂度:O(n)

    (7) Numofleaves (BiTree T)

    时间复杂度:O(n)

    空间复杂度:O(n)

    (7) BiWidth (BiTree T)

    时间复杂度:O(n)

    空间复杂度:O(n)

    (7) CopyBitree (BiTree T)

    时间复杂度:O(n)

    空间复杂度:O(n)

    (7) DestroyBiTree (BiTree T)

    时间复杂度:O(n)

    空间复杂度:O(n)

    5.测试结果及分析

    测试功能一:Create a binary tree and show the tree structure

    测试用例

    结果

    分析

    6423####51##7##

    124##5##36##7##

    #

    1234######

    调试功能二:Create a binary tree and show show the preoeder, inorder, postorder and levelorder

    测试用例

    结果

    分析

    6423####51##7##

    124##5##36##7##

    1234######

    测试功能三:Create a binary tree and calculate the number of nodes, leaves, height and width

    测试用例

    结果

    分析

    6423####51##7##

    124##5##36##7##

    1234######

    调试功能四:Create a binary tree, copy it, destory the original one and show the new tree

    测试用例

    结果

    分析

    6423####51##7##

    124##5##36##7##

    1234######

    6.实验体会和收获

    1.      掌握二叉树的递归特性
    2.      掌握二叉树的常用存储结构----二叉链表
    3.      掌握二叉树的创建、遍历等基本运算
    4.      了解递归函数的执行过程,学会编写递归程序

    代码

    Noah_BiTree.h

    1. 1. #ifndef __NOAH_BITREE_H__
    2. 2. #define __NOAH_BITREE_H__
    3. 3. #include
    4. 4. #include
    5. 5. #include
    6. 6. #include
    7. 7. #include
    8. 8. #include
    9. 9. using namespace std;
    10. 10. #define TElemType char
    11. 11. /*
    12. 12. 1. 对于创建的二叉树为空的情况,要能程序要能正常运行并识别。(5分)
    13. 13. 2. 对于空树,其他功能要可以识别、输出相应信息,并且程序不能异常终止。(5分)
    14. 14. */
    15. 15. typedef struct Node
    16. 16. {
    17. 17. TElemType data;
    18. 18. struct Node *lchild,*rchild;//左右孩子指针
    19. 19. }BiTNode,*BiTree;
    20. 20.
    21. 21. void CreateBiTree_Preorder(BiTree &T){
    22. 22. //使用先序遍历的输入创建一个二叉树,例如6423####51##7##
    23. 23. char x;
    24. 24. cin>>x;
    25. 25. if(x==' '||x=='#'){
    26. 26. T = NULL;
    27. 27. }
    28. 28. else {
    29. 29. T = (BiTree)malloc(sizeof(BiTNode));
    30. 30. if(x !='#')
    31. 31. T->data = (TElemType)x;
    32. 32. CreateBiTree_Preorder(T->lchild);
    33. 33. CreateBiTree_Preorder(T->rchild);
    34. 34. }
    35. 35. }
    36. 36.
    37. 37. void CreateBiTree_withhint(BiTree &T){
    38. 38. //向屏幕输出初始化二叉树的提示信息,调用CreateBiTree_Preorder()
    39. 39. cout<<"Please input a preorder sequence of a binary tree(example:6423####51##7##):"<
    40. 40. CreateBiTree_Preorder(T);
    41. 41. if(T==NULL) cout<<"Input is an empty BiTree."<
    42. 42. }
    43. 43.
    44. 44. int isBiTreeEmpty(BiTree T){
    45. 45. //判断二叉树是否为空,为空返回1,不为空返回0
    46. 46. if((T->data == NULL && T->lchild && T->rchild)||T==NULL)
    47. 47. return 1;
    48. 48. else
    49. 49. return 0;
    50. 50. }
    51. 51.
    52. 52. void preorder(BiTree T){
    53. 53. //使用先序遍历输出二叉树
    54. 54. if(T){
    55. 55. cout<data;
    56. 56. preorder(T->lchild);
    57. 57. preorder(T->rchild);
    58. 58. }
    59. 59. else
    60. 60. return;
    61. 61. //cout<<"Empty BiTree."<
    62. 62. }
    63. 63.
    64. 64. void inorder(BiTree T){
    65. 65. //使用中序遍历输出二叉树
    66. 66. if(T){
    67. 67. inorder(T->lchild);
    68. 68. cout<data;
    69. 69. inorder(T->rchild);
    70. 70. }
    71. 71. }
    72. 72.
    73. 73. void postorder(BiTree T){
    74. 74. //使用后序遍历输出二叉树
    75. 75. if(T){
    76. 76. postorder(T->lchild);
    77. 77. postorder(T->rchild);
    78. 78. cout<data;
    79. 79. }
    80. 80. }
    81. 81.
    82. 82. void leverorder(BiTree T){
    83. 83. //使用层次遍历输出二叉树
    84. 84. if(T){
    85. 85. queue q;
    86. 86. q.push(T);
    87. 87. while(!q.empty()){//当队列非空时,还有没有遍历的parent结点
    88. 88. BiTree temp = q.front();
    89. 89. q.pop();
    90. 90. cout<data;
    91. 91. if(temp->lchild!=NULL) q.push(temp->lchild);
    92. 92. if(temp->rchild!=NULL) q.push(temp->rchild);
    93. 93. }
    94. 94. }
    95. 95. }
    96. 96.
    97. 97. int NumofNode(BiTree T){
    98. 98. //返回二叉树节点数
    99. 99. if(!T) return 0;
    100. 100. else return 1 + NumofNode(T->lchild) + NumofNode(T->rchild);
    101. 101. }
    102. 102.
    103. 103. int Numofleaves(BiTree T){
    104. 104. //返回二叉树叶子数
    105. 105. int num = 0;
    106. 106. if(!T) return 0;
    107. 107. else{
    108. 108. if(T->lchild!=NULL) num = num + Numofleaves(T->lchild);
    109. 109. if(T->rchild!=NULL) num = num + Numofleaves(T->rchild);
    110. 110. if(T->lchild==NULL && T->rchild==NULL) return 1;
    111. 111. }
    112. 112. return num;
    113. 113. }
    114. 114.
    115. 115. int BiHight(BiTree T){
    116. 116. //返回二叉树高度
    117. 117. if(!T) return 0;
    118. 118. else{
    119. 119. int lefthight = BiHight(T->lchild);
    120. 120. int righthight = BiHight(T->rchild);
    121. 121. return (lefthight>=righthight)?lefthight+1:righthight+1;
    122. 122. }
    123. 123. }
    124. 124.
    125. 125. int BiWidth(BiTree T){
    126. 126. //返回二叉树宽度
    127. 127. if (isBiTreeEmpty(T)) {
    128. 128. return 0;
    129. 129. }
    130. 130. queue q;
    131. 131. int maxWidth = 1;
    132. 132. q.push(T);
    133. 133.
    134. 134. while (1) {
    135. 135. int len = q.size();
    136. 136. if (!len) {
    137. 137. break;
    138. 138. }
    139. 139. while (len--) {
    140. 140.
    141. 141. BiTree temp = q.front();
    142. 142. q.pop();
    143. 143. if (temp->lchild) {
    144. 144. q.push(temp->lchild);
    145. 145. }
    146. 146. if (temp->rchild) {
    147. 147. q.push(temp->rchild);
    148. 148. }
    149. 149. }
    150. 150. maxWidth = max(maxWidth, (int) q.size());
    151. 151. }
    152. 152. return maxWidth;
    153. 153. }
    154. 154.
    155. 155. void CopyBitree(BiTree source,BiTree &target){
    156. 156. //将source中的二叉树复制给target,原二叉树和复制的二叉树之间销毁操作不能互相影响
    157. 157. if(!source){
    158. 158. target = NULL;
    159. 159. return;
    160. 160. }
    161. 161.
    162. 162. else{
    163. 163. target = (BiTNode *)malloc(sizeof(BiTNode));
    164. 164. target->data = (TElemType)source->data;
    165. 165. CopyBitree(source->lchild,target->lchild);
    166. 166. CopyBitree(source->rchild,target->rchild);
    167. 167. }
    168. 168. }
    169. 169.
    170. 170.
    171. 171. void DestroyBiTree(BiTree &T){
    172. 172. //销毁二叉树并释放内存
    173. 173. if(isBiTreeEmpty(T)){
    174. 174. cout<<"DestroyBiTree succeed."<
    175. 175. return;
    176. 176. }
    177. 177. else{
    178. 178. if(T->lchild!=NULL) DestroyBiTree(T->lchild);
    179. 179. if(T->rchild!=NULL) DestroyBiTree(T->rchild);
    180. 180. free(T);
    181. 181. T = NULL;
    182. 182. }
    183. 183. }
    184. 184.
    185. 185. void DisplayBitree_control(BiTree n, bool left, string const& indent){
    186. 186. //DisplayBitree()函数的中间控制函数
    187. 187. if (n->rchild)
    188. 188. {
    189. 189. DisplayBitree_control(n->rchild, false, indent + (left ? "| " : " "));
    190. 190. }
    191. 191. cout << indent;
    192. 192. cout << (left ? '\\' : '/');
    193. 193. cout << "-----";
    194. 194. cout << n->data << endl;
    195. 195. if (n->lchild)
    196. 196. {
    197. 197. DisplayBitree_control(n->lchild, true, indent + (left ? " " : "| "));
    198. 198. }
    199. 199. }
    200. 200. void DisplayBitree(BiTree root){
    201. 201. //以树形结构形式输出二叉树
    202. 202. if(!root){
    203. 203. cout<<"An empty tree."<
    204. 204. return;
    205. 205. }
    206. 206. if (root->rchild)
    207. 207. {
    208. 208. DisplayBitree_control(root->rchild, false, "");
    209. 209. }
    210. 210. cout << root->data << endl;
    211. 211. if (root->lchild)
    212. 212. {
    213. 213. DisplayBitree_control(root->lchild, true, "");
    214. 214. }
    215. 215. }
    216. 216. #endif

     main.cpp

    1. 1. #include
    2. 2. #include
    3. 3. #include
    4. 4. #include
    5. 5. using namespace std;
    6. 6. #include "Noah_BiTree.h"
    7. 7. void Menue_gui();
    8. 8. void func1();
    9. 9. void func2();
    10. 10. void func3();
    11. 11. void func4();
    12. 12.
    13. 13. int main()
    14. 14. {
    15. 15. while(1){
    16. 16. Menue_gui();
    17. 17. int func;
    18. 18. scanf("%d",&func);
    19. 19. switch(func){
    20. 20. case 0:
    21. 21. exit(0);
    22. 22. case 1:
    23. 23. func1();break;
    24. 24. case 2:
    25. 25. func2();break;
    26. 26. case 3:
    27. 27. func3();break;
    28. 28. case 4:
    29. 29. func4();break;
    30. 30. default:
    31. 31. printf("Input error! Please try again!");
    32. 32. }
    33. 33. printf("\n");
    34. 34. system("pause");
    35. 35. }
    36. 36. return 0;
    37. 37. }
    38. 38.
    39. 39. //主界面
    40. 40. void Menue_gui(){
    41. 41. system("cls");
    42. 42. printf("**********************************Binary Tree calcuator**************************************\n");
    43. 43. printf("*********************************************************************************************\n");
    44. 44. printf("Menue:\n");
    45. 45. printf("\nExit this program------------------------------------------------------------------0.\n");
    46. 46. printf("\nCreate a binary tree and show the tree structure-----------------------------------1.\n");
    47. 47. printf("\nCreate a binary tree and show show the preoeder, inorder, postorder and levelorder-2.\n");
    48. 48. printf("\nCreate a binary tree and calculate the number of nodes, leaves, height and width---3.\n");
    49. 49. printf("\nCreate a binary tree, copy it, destory the original one and show the new tree------4.\n");
    50. 50. printf("\n**********************************************************************************************\n");
    51. 51. printf("Choose the function you want to use(input number):\n");
    52. 52. }
    53. 53.
    54. 54. void func1(){
    55. 55. system("cls");
    56. 56. printf("-----ENTER FUNCTION : Create a binary tree and show the tree structure--1.-----\n");
    57. 57. BiTree T1;
    58. 58. CreateBiTree_withhint(T1);
    59. 59. DisplayBitree(T1);
    60. 60. }
    61. 61. void func2(){
    62. 62. system("cls");
    63. 63. printf("-----ENTER FUNCTION : Create a binary tree and show show the preoeder, inorder, postorder and levelorder--2.-----\n");
    64. 64. BiTree T1;
    65. 65. CreateBiTree_withhint(T1);
    66. 66. cout<"The tree form of the Binary Tree is:"<
    67. 67. DisplayBitree(T1);
    68. 68. cout<"The preorder of the Binary Tree is:"<
    69. 69. preorder(T1);
    70. 70. cout<"The inorder of the Binary Tree is:"<
    71. 71. inorder(T1);
    72. 72. cout<"The postorder of the Binary Tree is:"<
    73. 73. postorder(T1);
    74. 74. cout<"The levelorder of the Binary Tree is:"<
    75. 75. leverorder(T1);
    76. 76. }
    77. 77. void func3(){
    78. 78. system("cls");
    79. 79. printf("-----ENTER FUNCTION : Create a binary tree and calculate the number of nodes, leaves, height and width--3.-----\n");
    80. 80. BiTree T1;
    81. 81. CreateBiTree_withhint(T1);
    82. 82. cout<"The tree form of the Binary Tree is:"<
    83. 83. DisplayBitree(T1);
    84. 84. cout<"The number of nodes is:"<<NumofNode(T1)<
    85. 85. cout<"The number of leaves is:"<<Numofleaves(T1)<
    86. 86. cout<"The height is:"<<BiHight(T1)<
    87. 87. cout<"The width is:"<<BiWidth(T1)<
    88. 88. }
    89. 89. void func4(){
    90. 90. system("cls");
    91. 91. printf("-----ENTER FUNCTION : Create a binary tree, copy it, destory the original one and show the new tree--4.-----\n");
    92. 92. BiTree T1;
    93. 93. CreateBiTree_withhint(T1);
    94. 94. cout<"The tree form of the [ORIGINAL] Binary Tree is:"<
    95. 95. DisplayBitree(T1);
    96. 96. BiTree T2;
    97. 97. CopyBitree(T1,T2);//复制T1到T2
    98. 98. DestroyBiTree(T1);//销毁T1
    99. 99. cout<"After destroy, the tree form of the [ORIGINAL] Binary Tree is:"<
    100. 100. DisplayBitree(T1);
    101. 101. cout<"The tree form of the [NEW] Binary Tree is:"<
    102. 102. DisplayBitree(T2);
    103. 103. }

  • 相关阅读:
    Springboot拦截器中注入Bean
    Jenkins 部署.net core 项目 - NU1301错误
    [python 刷题] 153 Find Minimum in Rotated Sorted Array
    【CLS数据淘金第四期】网络流日志-云联网日志分析
    Web3 | DID赛道之 Galxe(原 Project Galaxy)
    几个实用的MySQL内置函数使用方法
    模拟pdf运行js脚本触发xss攻击及防攻击
    1010hw
    Nacos服务注册中心
    Spring Boot 使用 Disruptor 做内部高性能消息队列
  • 原文地址:https://blog.csdn.net/standingflower/article/details/128126394