****************************************************** ****************************************************** *****
この記事の著者、MF22、HKUST の同級生である Noah Lazy Yangyang は、全員に宿題のアイデアを提供しています。直接コピーしないでください。! ! 一緒に学びましょう〜
****************************************************** ****************************************************** ******
目次
1.問題の説明
1.1基本機能
1. 二分木を作成する (10')
preorder traversal 入力を使用でき、# を使用してノードがないことを示すことができます。
たとえば、下の図では 6423####51##7## と入力できます。ここで、最初の 2 つの # はノード 3 の左右の子が空であることを示し、3 番目の # はノード 2 の右の子が空であることを示し、4 番目の # はノード 4 の右の子が空であることを示し、2 つの # はノード 3 の右の子が空であることを示します。 1 と 7 の後の # はそれぞれノードを表します。1 と 7 の左右の子ノードは空です。
他の入力方法を選択することもできますが、readme ファイルと実験レポートで明確にする必要があります。
2. バイナリ ツリーのトラバース (前順、インオーダー、ポストオーダー、層順トラバーサル) (20')
予約トラバーサル: 6423517
インオーダー トラバーサル: 3246157
注文後のトラバーサル: 3241756
レイヤー シーケンス トラバーサル: 6452173
3. 二分木の計算 (節数、葉数、高さ、幅など) (20')
ノード数: 7
葉の数: 3
高さ: 4
幅: 3
4. 二分木処理(コピー、破棄) (20分)
コピーすると、新しいバイナリ ツリーが作成されます。元のバイナリ ツリーとコピーされたバイナリ ツリーの間の破棄操作は、互いに影響を与えることはできません。
1.2堅牢性
- 作成されたバイナリ ツリーが空の場合、プログラムは正常に実行され、それを認識できる必要があります。(5点)
- 空のツリーの場合、他の関数が対応する情報を識別して出力できる必要があり、プログラムが異常終了することはありません。(5点)
1.3規範
- コード コメント
- プログラムのモジュール化
- フレンドリーなヒューマン コンピュータ インタラクション
2.アルゴリズムの説明
2.1データ構造の説明
プログラムで使用される主なデータ構造は、バイナリ ツリー (バイナリ リンク リスト) です。
主な変数の説明:
変数 |
タイプ |
例証する |
ノード、BiTNode |
構造 |
二分木ノードの構造 |
*バイツリー |
二分木ノードポインタ |
二分木ノードへのポインタ |
データ |
変数 (マクロ定義 TElemType、例では char によって決定) |
二分木ノードのデータ フィールド |
*子 |
二分木ノードポインタ |
ノードの左の子 |
*子供 |
二分木ノードポインタ |
ノードの右の子 |
TELemType |
マクロ定義 |
二分木ノードのデータ フィールドのタイプ |
2.2プログラム構造の説明
プログラムは主に Noah_BiTree.h ヘッダー ファイルと main.cpp メイン ファイルを含みます。ここで、Noah_BiTree.h はバイナリ リンク リスト データ構造 N の実装コード ヘッダー ファイルであり、main.cpp は主にメニューとの相互作用を実現します。関数インターフェイスとヘッダー ファイル呼び出しの関数。その具体的な構造を下図に示します。
3.デバッグ分析
デバッグ機能1:二分木を作成して木構造を表示
二分木を作成し、木の構造を表示する
テスト データの選択:
- 6423####51##7##
- 124##5##36##7##
- #
- 1234######
問題と解決策:
なし
デバッグ機能 2: 二分木を作成し、preoeder、inorder、postorder、levelorder を表示
preorder、inorder postorder、およびレベル トラバーサルを示すバイナリ ツリーを作成します。
テスト データの選択:
- 6423####51##7##
- 124##5##36##7##
- 1234######
問題と解決策:
なし
调试機能三:二分木を作成し、節数、葉数、高さ、幅を計算する
二分木を作成し、ノード、葉、高さ、幅の数を数えます
テスト データの選択:
- 6423####51##7##
- 124##5##36##7##
- 1234######
問題と解決策:
なし
调试功能四:二分木を作成し、それをコピーし、元の分木を破棄して、新しい木を表示します
二分木を作成してコピーし、元の木を破棄して新しい木を表示する
テスト データの選択:
- 6423####51##7##
- 124##5##36##7##
- 1234######
問題と解決策:
なし
4.アルゴリズムの時空間解析
(1) CreateBiTree_withhint(BiTree &T)
時間の複雑さ: O(n)
スペースの複雑さ: O(n)
(2) プレオーダー(BiTree T)
時間の複雑さ: O(n)
スペースの複雑さ: O(n)
(3) inorder(BiTree T)
時間の複雑さ: O(n)
スペースの複雑さ: O(n)
(4)通販(BiTree T)
時間の複雑さ: O(n)
スペースの複雑さ: O(n)
(5) levelorder(BiTree T)
時間の複雑さ: O(n)
スペースの複雑さ: O(n)
(6) NumofNode (BiTree T)
時間の複雑さ: O(n)
スペースの複雑さ: O(n)
(7) BiHight(バイツリー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.テスト結果と分析
テスト機能 1: バイナリ ツリーを作成し、ツリー構造を表示する
テストケース |
結果 |
分析する |
6423####51##7## |
√ |
|
124##5##36##7## |
√ |
|
# |
√ |
|
1234###### |
√ |
デバッグ機能 2: 二分木を作成し、preoeder、inorder、postorder、levelorder を表示
テストケース |
結果 |
分析する |
6423####51##7## |
√ |
|
124##5##36##7## |
√ |
|
1234###### |
√ |
测试功能三:二分木を作成し、節、葉、高さ、幅の数を計算する
テストケース |
結果 |
分析する |
6423####51##7## |
√ |
|
124##5##36##7## |
√ |
|
1234###### |
√ |
调试功能四:二分木を作成し、それをコピーし、元の分木を破棄して、新しい木を表示します
テストケース |
結果 |
分析する |
6423####51##7## |
√ |
|
124##5##36##7## |
√ |
|
1234###### |
√ |
6.実験体験と収穫
- 二分木の再帰的性質をマスターする
- バイナリ ツリーの共通ストレージ構造をマスターする----バイナリ リンク リスト
- 二分木の作成やトラバーサルなどの基本操作をマスターする
- 再帰関数の実行過程を理解し、再帰プログラムの書き方を学ぶ
コード
Noah_BiTree.h
1. #ifndef __NOAH_BITREE_H__
2. #define __NOAH_BITREE_H__
3. #include <stdlib.h>
4. #include <iostream>
5. #include <cstring>
6. #include <queue>
7. #include <string>
8. #include <iostream>
9. using namespace std;
10. #define TElemType char
11. /*
12. 1. 对于创建的二叉树为空的情况,要能程序要能正常运行并识别。(5分)
13. 2. 对于空树,其他功能要可以识别、输出相应信息,并且程序不能异常终止。(5分)
14. */
15. typedef struct Node
16. {
17. TElemType data;
18. struct Node *lchild,*rchild;//左右孩子指针
19. }BiTNode,*BiTree;
20.
21. void CreateBiTree_Preorder(BiTree &T){
22. //使用先序遍历的输入创建一个二叉树,例如6423####51##7##
23. char x;
24. cin>>x;
25. if(x==' '||x=='#'){
26. T = NULL;
27. }
28. else {
29. T = (BiTree)malloc(sizeof(BiTNode));
30. if(x !='#')
31. T->data = (TElemType)x;
32. CreateBiTree_Preorder(T->lchild);
33. CreateBiTree_Preorder(T->rchild);
34. }
35. }
36.
37. void CreateBiTree_withhint(BiTree &T){
38. //向屏幕输出初始化二叉树的提示信息,调用CreateBiTree_Preorder()
39. cout<<"Please input a preorder sequence of a binary tree(example:6423####51##7##):"<<endl;
40. CreateBiTree_Preorder(T);
41. if(T==NULL) cout<<"Input is an empty BiTree."<<endl;
42. }
43.
44. int isBiTreeEmpty(BiTree T){
45. //判断二叉树是否为空,为空返回1,不为空返回0
46. if((T->data == NULL && T->lchild && T->rchild)||T==NULL)
47. return 1;
48. else
49. return 0;
50. }
51.
52. void preorder(BiTree T){
53. //使用先序遍历输出二叉树
54. if(T){
55. cout<<T->data;
56. preorder(T->lchild);
57. preorder(T->rchild);
58. }
59. else
60. return;
61. //cout<<"Empty BiTree."<<endl;
62. }
63.
64. void inorder(BiTree T){
65. //使用中序遍历输出二叉树
66. if(T){
67. inorder(T->lchild);
68. cout<<T->data;
69. inorder(T->rchild);
70. }
71. }
72.
73. void postorder(BiTree T){
74. //使用后序遍历输出二叉树
75. if(T){
76. postorder(T->lchild);
77. postorder(T->rchild);
78. cout<<T->data;
79. }
80. }
81.
82. void leverorder(BiTree T){
83. //使用层次遍历输出二叉树
84. if(T){
85. queue<BiTree> q;
86. q.push(T);
87. while(!q.empty()){//当队列非空时,还有没有遍历的parent结点
88. BiTree temp = q.front();
89. q.pop();
90. cout<<temp->data;
91. if(temp->lchild!=NULL) q.push(temp->lchild);
92. if(temp->rchild!=NULL) q.push(temp->rchild);
93. }
94. }
95. }
96.
97. int NumofNode(BiTree T){
98. //返回二叉树节点数
99. if(!T) return 0;
100. else return 1 + NumofNode(T->lchild) + NumofNode(T->rchild);
101. }
102.
103. int Numofleaves(BiTree T){
104. //返回二叉树叶子数
105. int num = 0;
106. if(!T) return 0;
107. else{
108. if(T->lchild!=NULL) num = num + Numofleaves(T->lchild);
109. if(T->rchild!=NULL) num = num + Numofleaves(T->rchild);
110. if(T->lchild==NULL && T->rchild==NULL) return 1;
111. }
112. return num;
113. }
114.
115. int BiHight(BiTree T){
116. //返回二叉树高度
117. if(!T) return 0;
118. else{
119. int lefthight = BiHight(T->lchild);
120. int righthight = BiHight(T->rchild);
121. return (lefthight>=righthight)?lefthight+1:righthight+1;
122. }
123. }
124.
125. int BiWidth(BiTree T){
126. //返回二叉树宽度
127. if (isBiTreeEmpty(T)) {
128. return 0;
129. }
130. queue<BiTree> q;
131. int maxWidth = 1;
132. q.push(T);
133.
134. while (1) {
135. int len = q.size();
136. if (!len) {
137. break;
138. }
139. while (len--) {
140.
141. BiTree temp = q.front();
142. q.pop();
143. if (temp->lchild) {
144. q.push(temp->lchild);
145. }
146. if (temp->rchild) {
147. q.push(temp->rchild);
148. }
149. }
150. maxWidth = max(maxWidth, (int) q.size());
151. }
152. return maxWidth;
153. }
154.
155. void CopyBitree(BiTree source,BiTree &target){
156. //将source中的二叉树复制给target,原二叉树和复制的二叉树之间销毁操作不能互相影响
157. if(!source){
158. target = NULL;
159. return;
160. }
161.
162. else{
163. target = (BiTNode *)malloc(sizeof(BiTNode));
164. target->data = (TElemType)source->data;
165. CopyBitree(source->lchild,target->lchild);
166. CopyBitree(source->rchild,target->rchild);
167. }
168. }
169.
170.
171. void DestroyBiTree(BiTree &T){
172. //销毁二叉树并释放内存
173. if(isBiTreeEmpty(T)){
174. cout<<"DestroyBiTree succeed."<<endl;
175. return;
176. }
177. else{
178. if(T->lchild!=NULL) DestroyBiTree(T->lchild);
179. if(T->rchild!=NULL) DestroyBiTree(T->rchild);
180. free(T);
181. T = NULL;
182. }
183. }
184.
185. void DisplayBitree_control(BiTree n, bool left, string const& indent){
186. //DisplayBitree()函数的中间控制函数
187. if (n->rchild)
188. {
189. DisplayBitree_control(n->rchild, false, indent + (left ? "| " : " "));
190. }
191. cout << indent;
192. cout << (left ? '\\' : '/');
193. cout << "-----";
194. cout << n->data << endl;
195. if (n->lchild)
196. {
197. DisplayBitree_control(n->lchild, true, indent + (left ? " " : "| "));
198. }
199. }
200. void DisplayBitree(BiTree root){
201. //以树形结构形式输出二叉树
202. if(!root){
203. cout<<"An empty tree."<<endl;
204. return;
205. }
206. if (root->rchild)
207. {
208. DisplayBitree_control(root->rchild, false, "");
209. }
210. cout << root->data << endl;
211. if (root->lchild)
212. {
213. DisplayBitree_control(root->lchild, true, "");
214. }
215. }
216. #endif
main.cpp
1. #include <stdio.h>
2. #include <string.h>
3. #include <stdlib.h>
4. #include <iostream>
5. using namespace std;
6. #include "Noah_BiTree.h"
7. void Menue_gui();
8. void func1();
9. void func2();
10. void func3();
11. void func4();
12.
13. int main()
14. {
15. while(1){
16. Menue_gui();
17. int func;
18. scanf("%d",&func);
19. switch(func){
20. case 0:
21. exit(0);
22. case 1:
23. func1();break;
24. case 2:
25. func2();break;
26. case 3:
27. func3();break;
28. case 4:
29. func4();break;
30. default:
31. printf("Input error! Please try again!");
32. }
33. printf("\n");
34. system("pause");
35. }
36. return 0;
37. }
38.
39. //主界面
40. void Menue_gui(){
41. system("cls");
42. printf("**********************************Binary Tree calcuator**************************************\n");
43. printf("*********************************************************************************************\n");
44. printf("Menue:\n");
45. printf("\nExit this program------------------------------------------------------------------0.\n");
46. printf("\nCreate a binary tree and show the tree structure-----------------------------------1.\n");
47. printf("\nCreate a binary tree and show show the preoeder, inorder, postorder and levelorder-2.\n");
48. printf("\nCreate a binary tree and calculate the number of nodes, leaves, height and width---3.\n");
49. printf("\nCreate a binary tree, copy it, destory the original one and show the new tree------4.\n");
50. printf("\n**********************************************************************************************\n");
51. printf("Choose the function you want to use(input number):\n");
52. }
53.
54. void func1(){
55. system("cls");
56. printf("-----ENTER FUNCTION : Create a binary tree and show the tree structure--1.-----\n");
57. BiTree T1;
58. CreateBiTree_withhint(T1);
59. DisplayBitree(T1);
60. }
61. void func2(){
62. system("cls");
63. printf("-----ENTER FUNCTION : Create a binary tree and show show the preoeder, inorder, postorder and levelorder--2.-----\n");
64. BiTree T1;
65. CreateBiTree_withhint(T1);
66. cout<<endl<<"The tree form of the Binary Tree is:"<<endl;
67. DisplayBitree(T1);
68. cout<<endl<<"The preorder of the Binary Tree is:"<<endl;
69. preorder(T1);
70. cout<<endl<<"The inorder of the Binary Tree is:"<<endl;
71. inorder(T1);
72. cout<<endl<<"The postorder of the Binary Tree is:"<<endl;
73. postorder(T1);
74. cout<<endl<<"The levelorder of the Binary Tree is:"<<endl;
75. leverorder(T1);
76. }
77. void func3(){
78. system("cls");
79. printf("-----ENTER FUNCTION : Create a binary tree and calculate the number of nodes, leaves, height and width--3.-----\n");
80. BiTree T1;
81. CreateBiTree_withhint(T1);
82. cout<<endl<<"The tree form of the Binary Tree is:"<<endl;
83. DisplayBitree(T1);
84. cout<<endl<<"The number of nodes is:"<<NumofNode(T1)<<endl;
85. cout<<endl<<"The number of leaves is:"<<Numofleaves(T1)<<endl;
86. cout<<endl<<"The height is:"<<BiHight(T1)<<endl;
87. cout<<endl<<"The width is:"<<BiWidth(T1)<<endl;
88. }
89. void func4(){
90. system("cls");
91. printf("-----ENTER FUNCTION : Create a binary tree, copy it, destory the original one and show the new tree--4.-----\n");
92. BiTree T1;
93. CreateBiTree_withhint(T1);
94. cout<<endl<<"The tree form of the [ORIGINAL] Binary Tree is:"<<endl;
95. DisplayBitree(T1);
96. BiTree T2;
97. CopyBitree(T1,T2);//复制T1到T2
98. DestroyBiTree(T1);//销毁T1
99. cout<<endl<<"After destroy, the tree form of the [ORIGINAL] Binary Tree is:"<<endl;
100. DisplayBitree(T1);
101. cout<<endl<<"The tree form of the [NEW] Binary Tree is:"<<endl;
102. DisplayBitree(T2);
103. }