二叉树的创建和相关算法

水深无声 2022-08-22 13:25 252阅读 0赞

Center

二叉树是一种非常重要的数据结构,它是分支结构的基础,今天本人将写一篇博客来叙述一下其相关的算法以及二叉树的创建过程!

1:二叉树的创建:

主要有 先序,中序,后序,层序创建几种方式,其中前三种建立在二叉树遍历方式的基础上的。

(1):先序创建

先序创建就是先创建根节点,随后依次创建其左子树和右子树,我们可以采用递归的方法来实现,因为二叉树本身就是建立在递归算法的基础上的。

(2):中序和后序创建:

明白了前序创建二叉树的方式,中序和后续我们也可以类比出来,所谓前中后序,就是创建根节点的顺序而已。

(3):层序遍历和创建:

Center 1

以上图片反映的层序遍历的过程,层序遍历是建立在队列的基础上的,首先如果一颗二叉树非空,让根节点入队,如果根节点的左子树后右子树非空,则根节点出队并打印它的数据域的值,左右子树先后入队(谁不空谁入队),随后就是一个递归的过程了。

可见层序遍历是从上到下,从左到右的一个遍历过程。

所以我们也可以层序创建一个二叉树:首先创建根节点,如果根节点的左孩子和右孩子指针没有指向虚结点,则创建左子树和右子树,也是通过递归的方式来创建的。

二叉树代码:

函数文件 Bittree.c:

  1. #include "Bittree.h"
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <assert.h>
  5. tree *Creat(tree* root, tree*(*ptree)(tree *root))
  6. {
  7. root = ptree(root);
  8. return root;
  9. }
  10. tree *Tier_creat(tree* root) //层序创建二叉树 root为根节点
  11. {
  12. tree *s = NULL;
  13. datatype data = 0;
  14. tree *Tree_arr[MAX] = { 0 }; //创建一个存储二叉树结点的队列
  15. int front = 1; //front为队列指针初值
  16. int rear = 0; //rear为队列末尾指针初值
  17. printf("层数创建二叉树,以-1表示虚结点,-2表示结束!\n");
  18. scanf("%d", &data);
  19. while (data != -2)
  20. {
  21. s = NULL;
  22. if (data != -1)
  23. {
  24. s =(tree*) malloc(sizeof(tree)* 1);
  25. s->data = data;
  26. s->Lchild = NULL;
  27. s->Rchild = NULL;
  28. }
  29. rear++;
  30. Tree_arr[rear] = s; //双亲节点入队
  31. if (rear == 1) root = s; //如果rear为队头指针,则其队列中存储的为二叉树的根节点
  32. else
  33. {
  34. if (Tree_arr[rear] && s) //孩子和双亲都不是虚结点
  35. {
  36. if (rear % 2 == 0) Tree_arr[front]->Lchild = s; //新节点是左孩子
  37. if (rear % 2 == 1)
  38. {
  39. Tree_arr[front]->Rchild = s; //新节点是右孩子
  40. front++; //如果是此时rear指向右孩子,则出队,下一个节点进队
  41. }
  42. }
  43. }
  44. scanf("%d", &data);
  45. }
  46. return root;
  47. }
  48. tree *DLR_creat(tree* root) //先序创建二叉树
  49. {
  50. printf("以-1表示指针域为空,以-2表示结束创建过程\n");
  51. root = NULL;
  52. int data = 0;
  53. printf("请输入数据:");
  54. scanf("%d", &data);
  55. if (data == -1)
  56. return NULL;
  57. root = (tree*)malloc(sizeof(tree)* 1);
  58. if (root == NULL)
  59. {
  60. printf("创建失败!\n");
  61. exit(EXIT_FAILURE);
  62. }
  63. root->data = data;
  64. root->Lchild=DLR_creat(root->Lchild);
  65. root->Rchild = DLR_creat(root->Rchild);
  66. return root;
  67. }
  68. tree *LDR_creat(tree* root) //中序创建二叉树
  69. {
  70. printf("以-1表示指针域为空,以-2表示结束创建过程\n");
  71. root = NULL;
  72. int data = 0;
  73. printf("请输入数据:");
  74. scanf("%d", &data);
  75. if (data == -1)
  76. return NULL;
  77. root->Lchild = DLR_creat(root->Lchild);
  78. root = (tree*)malloc(sizeof(tree)* 1);
  79. if (root == NULL)
  80. {
  81. printf("创建失败!\n");
  82. exit(EXIT_FAILURE);
  83. }
  84. root->data = data;
  85. root->Rchild = DLR_creat(root->Rchild);
  86. return root;
  87. }
  88. tree *RLD_creat(tree* root) //后序创建二叉树
  89. {
  90. printf("以-1表示指针域为空,以-2表示结束创建过程\n");
  91. root = NULL;
  92. int data = 0;
  93. printf("请输入数据:");
  94. scanf("%d", &data);
  95. if (data == -1)
  96. return NULL;
  97. root->Lchild = DLR_creat(root->Lchild);
  98. root->Rchild = DLR_creat(root->Rchild);
  99. root = (tree*)malloc(sizeof(tree)* 1);
  100. if (root == NULL)
  101. {
  102. printf("创建失败!\n");
  103. exit(EXIT_FAILURE);
  104. }
  105. root->data = data;
  106. return root;
  107. }
  108. void Print_Tree(tree *root, void(*ptree)(tree *root)) //遍历二叉树
  109. {
  110. assert(root);
  111. if (root == NULL)
  112. {
  113. printf("树是空树!\n");
  114. return;
  115. }
  116. else
  117. {
  118. ptree(root);
  119. printf("\n");
  120. }
  121. }
  122. void DLR_Print(tree *root) //先序遍历二叉树
  123. {
  124. if (root != NULL)
  125. {
  126. printf("%d ", root->data);
  127. DLR_Print(root->Lchild);
  128. DLR_Print(root->Rchild);
  129. }
  130. return;
  131. }
  132. void LDR_Print(tree *root) //中序遍历二叉树
  133. {
  134. if (root != NULL)
  135. {
  136. DLR_Print(root->Lchild);
  137. printf("%d ", root->data);
  138. DLR_Print(root->Rchild);
  139. }
  140. return;
  141. }
  142. void RLD_Print(tree *root) //后序遍历二 叉树
  143. {
  144. if (root != NULL)
  145. {
  146. DLR_Print(root->Lchild);
  147. DLR_Print(root->Rchild);
  148. printf("%d ", root->data);
  149. }
  150. return;
  151. }
  152. void Tie_Print(tree *root) //层序遍历二叉树
  153. {
  154. tree* arry[MAX] = { 0 };
  155. int rear = 1;
  156. int front = 0;
  157. if (root == NULL)
  158. {
  159. printf("二叉树为空!\n");
  160. return;
  161. }
  162. else
  163. {
  164. arry[0] = root; //如果二叉树不为空,根节点先入队。
  165. while (front < rear) //循环条件 队列非空
  166. {
  167. if (arry[front])
  168. {
  169. printf("%d ", arry[front]->data);
  170. arry[rear++] = arry[front]->Lchild;
  171. arry[rear++] = arry[front]->Rchild;
  172. front++;
  173. }
  174. else
  175. {
  176. front++;
  177. }
  178. }
  179. }
  180. }
  181. int Deep_tree(tree *root) //求二叉树的深度
  182. {
  183. assert(root);
  184. int left = 0;
  185. int right = 0;
  186. int deep = 0;
  187. if (root != NULL)
  188. {
  189. left=Deep_tree(root->Lchild); //求左子树深度
  190. right = Deep_tree(root->Rchild); //求右子树深度
  191. deep = left > right ? (left + 1) : (right + 1);
  192. }
  193. return deep;
  194. }
  195. int Node_du(tree *root) //求某个节点的度
  196. {
  197. assert(root);
  198. int ret = 0;
  199. if (root == NULL)
  200. return 0;
  201. else
  202. {
  203. if (root->Lchild != NULL)
  204. ret++;
  205. if (root->Rchild != NULL)
  206. ret++;
  207. return ret;
  208. }
  209. }
  210. int tree_Node(tree *root)
  211. {
  212. assert(root);
  213. int ret = 0;
  214. if (root == NULL)
  215. return 0;
  216. if (root->Lchild == NULL&&root->Rchild == NULL) //叶子节点
  217. return 1;
  218. ret =1+ tree_Node(root->Lchild) + tree_Node(root->Rchild);
  219. return ret;
  220. }
  221. tree* search_Node(tree *root, datatype data) //查找值为data的节点
  222. {
  223. assert(root);
  224. tree *p=NULL;
  225. if (root == NULL)
  226. {
  227. printf("树是空树!\n");
  228. return NULL;
  229. }
  230. else
  231. {
  232. if (root->data == data)
  233. return root;
  234. if (root->Lchild != NULL)
  235. {
  236. p = search_Node(root->Lchild,data);
  237. if (p != NULL)
  238. return p;
  239. }
  240. if (root->Rchild != NULL)
  241. {
  242. p = search_Node(root->Rchild,data);
  243. if (p != NULL)
  244. return p;
  245. }
  246. return NULL; //没找到返回空
  247. }
  248. }
  249. void Deal_tree(tree *root) //释放内存
  250. {
  251. assert(root);
  252. if (root == NULL)
  253. return;
  254. Deal_tree(root->Lchild);
  255. Deal_tree(root->Rchild);
  256. free(root);
  257. root = NULL;
  258. }

头文件 Bittree.h

  1. #ifndef __BITTREE_H__
  2. #define __BITTREE_H__
  3. #define _CRT_SECURE_NO_WARNINGS
  4. #define MAX 100
  5. typedef int datatype;
  6. typedef struct Bittree
  7. {
  8. datatype data;
  9. struct Bittree *Lchild;
  10. struct Bittree *Rchild;
  11. }tree;
  12. typedef struct
  13. {
  14. datatype Elem_data[MAX];
  15. int length;
  16. }Tree_arry;
  17. tree *Tier_creat(tree* root); //层序创建二叉树 root为根节点
  18. tree *DLR_creat(tree* root); //先序创建二叉树
  19. tree *LDR_creat(tree* root); //中序创建二叉树
  20. tree *RLD_creat(tree* root); //后序创建二叉树
  21. tree *Creat(tree* root,tree*(*ptree)(tree *root)); //创建二叉树
  22. void Print_Tree(tree *root, void(*ptree)(tree *root)); //遍历二叉树
  23. void DLR_Print(tree *root); //先序遍历二叉树
  24. void LDR_Print(tree *root); //中序遍历二叉树
  25. void RLD_Print(tree *root); //后序遍历二叉树
  26. void Tie_Print(tree *root); //层序遍历二叉树
  27. int Deep_tree(tree *root); //求二叉树的深度
  28. int Node_du(tree *root); //求某个节点的度
  29. int tree_Node(tree *root); //求树的节点的个数
  30. tree* search_Node(tree *root, datatype data); //查找值为data的节点
  31. void Deal_tree(tree *root); //释放内存
  32. #endif __BITTREE_H__

测试文件test.c:

  1. #include "Bittree.h"
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. void Init()
  5. {
  6. printf("1:二叉树的创建\n");
  7. printf("2:二叉树的遍历\n");
  8. printf("3:二叉树的深度查询\n");
  9. printf("4:二叉树的某一个节点的度的查询\n");
  10. printf("5:清空二叉树\n");
  11. printf("0:退出\n");
  12. }
  13. void Init_Print()
  14. {
  15. printf("0:层序遍历二叉树.\n");
  16. printf("1:先序遍历二叉树.\n");
  17. printf("2:后序遍历二叉树.\n");
  18. printf("3:中序遍历二叉树.\n");
  19. }
  20. void Init_Creat()
  21. {
  22. printf("0:层序创建二叉树.\n");
  23. printf("1:先序创建二叉树.\n");
  24. printf("2:后序创建二叉树.\n");
  25. printf("3:中序创建二叉树.\n");
  26. }
  27. void test()
  28. {
  29. int ret;
  30. int key=0;
  31. int choose;
  32. datatype data=0;
  33. tree *root = NULL;
  34. tree *node = NULL;
  35. tree* (*Tree_C[4])(tree *root) = { 0 }; //函数指针数组存放二叉树的创建方式
  36. void(*Tree_p[4])(tree *root) = { 0 }; //函数指针数组存放二叉树的遍历方式
  37. Tree_C[0] = Tier_creat;
  38. Tree_C[1] = DLR_creat;
  39. Tree_C[2] = LDR_creat;
  40. Tree_C[3] = RLD_creat;
  41. Tree_p[0] = Tie_Print;
  42. Tree_p[1] = DLR_Print;
  43. Tree_p[2] = LDR_Print;
  44. Tree_p[3] = DLR_Print;
  45. while (1)
  46. {
  47. printf("请输入你的选择:");
  48. scanf("%d", &key);
  49. switch (key)
  50. {
  51. case 0:
  52. printf("Program Over!!\n");
  53. exit(EXIT_FAILURE);
  54. break;
  55. case 1:
  56. Init_Creat();
  57. do
  58. {
  59. printf("请输入你的选择:");
  60. scanf("%d", &choose);
  61. } while (choose <= 0 && choose >= 3);
  62. root = Creat(root, Tree_C[choose]);
  63. break;
  64. case 2:
  65. Init_Print();
  66. do
  67. {
  68. printf("请输入你的选择:");
  69. scanf("%d", &choose);
  70. } while (choose <= 0 && choose >= 3);
  71. Print_Tree(root, Tree_p[choose]);
  72. break;
  73. case 3:
  74. ret = Deep_tree(root);
  75. printf("二叉树的深度为:%d\n", ret);
  76. break;
  77. case 4:
  78. printf("请输入你要查询节点所保存的数据:");
  79. scanf("%d", &data);
  80. node=search_Node(root, data);
  81. if (node == NULL)
  82. {
  83. printf("你所要查询的节点不存在!\n");
  84. exit(EXIT_FAILURE);
  85. }
  86. ret = Node_du(node);
  87. printf("数据为%d的节点的度为:%d\n",data, ret);
  88. break;
  89. case 5:
  90. Deal_tree(root);
  91. printf("清空成功!\n");
  92. break;
  93. }
  94. }
  95. }
  96. int main()
  97. {
  98. Init();
  99. test();
  100. system("pause");
  101. return 0;
  102. }

如果上述叙述有相关问题请大家能指出,本人邮箱:597995302@qq.com

发表评论

表情:
评论列表 (有 0 条评论,252人围观)

还没有评论,来说两句吧...

相关阅读

    相关 相关算法题思想

    二叉树是面试经常会考到的一个知识点,关于二叉树延伸的应用也很广泛。二叉树的核心是递归,但我们在遇到二叉树相关的问题时,如果纠结于递归这个点,很可能陷进去,毕竟人的大脑装不下那么

    相关 创建相关算法

    ![Center][] 二叉树是一种非常重要的数据结构,它是分支结构的基础,今天本人将写一篇博客来叙述一下其相关的算法以及二叉树的创建过程! 1:二叉树的创建: 主要有

    相关 创建

    二叉树的层序创建 创建步骤: 概括:队列里面出一个元素,输入两个元素作为这个元素的左右结点,然后将这两个元素中不为0的元素接着入队列 1. 先输入第一个数据,如果第

    相关 iOS 相关算法实现

    什么是二叉树? 在计算机科学中,二叉树是每个节点最多有两个子树的树结构。通常子树被称作“左子树”和“右子树”,左子树和右子树同时也是二叉树。二叉树的子树有左右之分,并且次