当前位置:   article > 正文

【数据结构】二叉树的销毁 & 二叉树系列所有源代码(终章)

二叉树的销毁

目录

一,二叉树的销毁 

二,二叉树系列所有源代码

BTee.h

BTee.c

Queue.h

Queue.c


一,二叉树的销毁 

二叉树建好了,利用完了,也该把申请的动态内存空间给释放了,那要如何释放呢?

我们还是以这棵树为例,要把这棵树销毁掉,其实就是把树上的结点全部释放掉,但是呢这个释放的顺序挺讲究的,对于树,我们的思想首先就是,前序遍历,中序遍历,后序遍历,层序遍历的思想,那这棵树到底用什么思想好呢?

我们先来分析一下,要释放以(1)为根结点的树就相当于释放左子树(2)和右子树(4)和自身的结点,然后呢以(2),(4)为根结点的树也是同理,层层递归下去,这不就符合后序遍历的思想吗,先左子树-->右子树-->根结点!所以销毁这棵树的思路就是后序遍历的思路

既然思路已经确定了,我们就要开始实现了!

大事化小:先释放结点的左子树,再释放其右子树然后在释放本身结点!

结束条件:当结点为空时返回 NULL ;

源代码

  1. //二叉树的销毁
  2. void BinaryTreeDestory(BTNode* root)
  3. {
  4. //判空
  5. if (root == NULL)
  6. {
  7. return NULL;
  8. }
  9. //释放左子树
  10. BinaryTreeDestory(root->left);
  11. //释放右子树
  12. BinaryTreeDestory(root->right);
  13. //释放本身结点
  14. free(root);
  15. }

 这就 ok 了,只要捋清楚思路了,就很简单了;

经过了9个阶段的学习,二叉树的初阶部分也是迎来了结尾,为什么说是初阶部分呢?因为一些更复杂的树的内容不太方便用 c 语言来讲解展示,等后面博主介绍完了 c++ 再来絮叨絮叨,同志们莫急,革命的道路还需一步一步向前走!

二,二叉树系列所有源代码

我们总共历经了九个阶段的学习,二叉树已是随便拿捏了!下面是这九个阶段以及二叉树初阶部分的所以源代码:

BTee.h

  1. #pragma once
  2. #include<stdio.h>
  3. #include<assert.h>
  4. #include<stdlib.h>
  5. typedef int BTDataType;
  6. //二叉链
  7. typedef struct BinaryTreeNode
  8. {
  9. BTDataType data; // 当前结点值域
  10. struct BinaryTreeNode* left; // 指向当前节点左孩子
  11. struct BinaryTreeNode* right; // 指向当前节点右孩子
  12. }BTNode;
  13. //动态创立新结点
  14. BTNode* BuyNode(BTDataType x);
  15. //创建二叉树
  16. BTNode* GreatBTree();
  17. //前序遍历
  18. void PrevOrder(BTNode* root);
  19. //中序遍历
  20. void InOrder(BTNode* root);
  21. //后序遍历
  22. void PostOrder(BTNode* root);
  23. //结点个数
  24. int SumNode(BTNode* root);
  25. //叶子结点个数
  26. int LeafNode(BTNode* root);
  27. //二叉树高度
  28. int HeightTree(BTNode* root);
  29. //二叉树第k层结点个数
  30. int BTreeLeveSize(BTNode* root, int k);
  31. //二叉树查找值为x的结点
  32. BTNode* BTreeFine(BTNode* root, int x);
  33. //层序遍历
  34. void LevelOrder(BTNode* root);
  35. //二叉树的销毁
  36. void BinaryTreeDestory(BTNode* root);
  37. // 通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树
  38. BTNode* BTCreate(BTDataType* a,int* i);
  39. // 判断二叉树是否是完全二叉树
  40. int BinaryTreeComplete(BTNode* root);

BTee.c

  1. #define _CRT_SECURE_NO_WARNINGS 1
  2. #include"BTree.h"
  3. #include"Queue.h"
  4. //动态创立新结点
  5. BTNode* BuyNode(BTDataType x)
  6. {
  7. BTNode* newnode = (BTNode*)malloc(sizeof(BTNode));
  8. assert(newnode);
  9. newnode->data = x;
  10. newnode->left = NULL;
  11. newnode->right = NULL;
  12. return newnode;
  13. }
  14. //创建二叉树
  15. BTNode* GreatBTree()
  16. {
  17. BTNode* node1 = BuyNode(1);
  18. BTNode* node2 = BuyNode(2);
  19. BTNode* node3 = BuyNode(3);
  20. BTNode* node4 = BuyNode(4);
  21. BTNode* node5 = BuyNode(5);
  22. BTNode* node6 = BuyNode(6);
  23. node1->left = node2;
  24. node1->right = node4;
  25. node2->left = node3;
  26. node4->left = node5;
  27. node4->right = node6;
  28. return node1;
  29. }
  30. //前序遍历
  31. void PrevOrder(BTNode* root)
  32. {
  33. if (root == NULL)
  34. {
  35. printf("N ");
  36. return;
  37. }
  38. printf("%c ", root->data);
  39. PrevOrder(root->left);
  40. PrevOrder(root->right);
  41. }
  42. //中序遍历
  43. void InOrder(BTNode* root)
  44. {
  45. if (root == NULL)
  46. {
  47. printf("N ");
  48. return NULL;
  49. }
  50. InOrder(root->left);
  51. printf("%c ", root->data);
  52. InOrder(root->right);
  53. }
  54. //后序遍历
  55. void PostOrder(BTNode* root)
  56. {
  57. if (root == NULL)
  58. {
  59. printf("N ");
  60. return;
  61. }
  62. PostOrder(root->left);
  63. PostOrder(root->right);
  64. printf("%d ", root->data);
  65. }
  66. //结点个数
  67. int SumNode(BTNode* root)
  68. {
  69. return root == NULL ? 0 : SumNode(root->left) + SumNode(root->right) + 1;
  70. }
  71. //叶子结点个数
  72. int LeafNode(BTNode* root)
  73. {
  74. if (root == NULL)
  75. {
  76. return 0;
  77. }
  78. if (root->left==NULL && root->right==NULL)
  79. {
  80. return 1;
  81. }
  82. else
  83. {
  84. return LeafNode(root->left) + LeafNode(root->right);
  85. }
  86. }
  87. //二叉树高度
  88. int HeightTree(BTNode* root)
  89. {
  90. if (root == NULL)
  91. {
  92. return 0;
  93. }
  94. int left = HeightTree(root->left);
  95. int right = HeightTree(root->right);
  96. return left > right ? left + 1 : right + 1;
  97. }
  98. //二叉树第k层结点个数
  99. int BTreeLeveSize(BTNode* root, int k)
  100. {
  101. if (root == NULL)
  102. {
  103. return 0;
  104. }
  105. if (k == 1)
  106. {
  107. return 1;
  108. }
  109. return BTreeLeveSize(root->left, k - 1) + BTreeLeveSize(root->right, k - 1);
  110. }
  111. //二叉树查找值为x的结点
  112. BTNode* BTreeFine(BTNode* root, int x)
  113. {
  114. if (root == NULL)
  115. {
  116. return NULL;
  117. }
  118. if (root->data == x)
  119. {
  120. return root;
  121. }
  122. if (BTreeFine(root->left, x) == NULL)
  123. {
  124. return BTreeFine(root->right, x);
  125. }
  126. else
  127. {
  128. return BTreeFine(root->left, x);
  129. }
  130. }
  131. //层序遍历
  132. void LevelOrder(BTNode* root)
  133. {
  134. Queue q;
  135. // 初始化队列
  136. QueueInit(&q);
  137. // 队尾入队列
  138. if (root)
  139. {
  140. QueuePush(&q, root);
  141. }
  142. while (!QueueEmpty(&q))
  143. {
  144. printf("%d ", QueueFront(&q)->data);
  145. BTNode* cur = QueueFront(&q);
  146. // 队头出队列
  147. QueuePop(&q);
  148. if (cur->left)
  149. {
  150. QueuePush(&q, cur->left);
  151. }
  152. if (cur->right)
  153. {
  154. QueuePush(&q, cur->right);
  155. }
  156. }
  157. }
  158. //二叉树的销毁
  159. void BinaryTreeDestory(BTNode* root)
  160. {
  161. //判空
  162. if (root == NULL)
  163. {
  164. return NULL;
  165. }
  166. //释放左子树
  167. BinaryTreeDestory(root->left);
  168. //释放右子树
  169. BinaryTreeDestory(root->right);
  170. //释放本身结点
  171. free(root);
  172. }
  173. void _BinaryTreeCreate(BTNode* node, BTDataType* a,int* pi)
  174. {
  175. if (node == NULL)
  176. {
  177. return;
  178. }
  179. node->left= BuyNode(a[(*pi)++]);
  180. node->right= BuyNode(a[(*pi)++]);
  181. }
  182. // 通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树
  183. BTNode* BinaryTreeCreate(BTDataType* a, int n, int* pi)
  184. {
  185. if (a == NULL)
  186. {
  187. return NULL;
  188. }
  189. BTNode* node1= BuyNode(a[(*pi)++]);
  190. _BinaryTreeCreate(node1, a, pi);
  191. return node1;
  192. }
  193. // 通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树
  194. BTNode* BTCreate(BTDataType* arr, int*i)
  195. {
  196. if (arr[(*i)] == '#')
  197. {
  198. (*i)++;
  199. return NULL;
  200. }
  201. BTNode* root = BuyNode(arr[(*i)++]);
  202. root->left = BTCreate(arr, i);
  203. root->right = BTCreate(arr, i);
  204. return root;
  205. }
  206. // 判断二叉树是否是完全二叉树
  207. int BinaryTreeComplete(BTNode* root)
  208. {
  209. Queue q;
  210. // 初始化队列
  211. QueueInit(&q);
  212. // 队尾人队列
  213. QueuePush(&q,root);
  214. while(QueueFront(&q))
  215. {
  216. BTNode* cur = QueueFront(&q);
  217. // 队头出队列
  218. QueuePop(&q);
  219. QueuePush(&q, cur->left);
  220. QueuePush(&q, cur->right);
  221. }
  222. while (!QueueEmpty(&q))
  223. {
  224. // 队头出队列
  225. QueuePop(&q);
  226. if (QueueFront(&q) != NULL)
  227. {
  228. BinaryTreeDestory(root);
  229. return 0;
  230. }
  231. }
  232. return 1;
  233. }

下面是【栈】的源代码,二叉树的层序遍历用的着,这边也发给大家了:

Queue.h

  1. #define _CRT_SECURE_NO_WARNINGS 1
  2. #pragma once
  3. #include<stdio.h>
  4. #include<assert.h>
  5. #include<stdlib.h>
  6. #include"BTree.h"
  7. typedef BTNode* QDataType;
  8. //结点
  9. typedef struct QListNode
  10. {
  11. struct QListNode* next;
  12. QDataType data;
  13. }QNode;
  14. // 队列
  15. typedef struct Queue
  16. {
  17. QNode* front; // 队头
  18. QNode* rear; //队尾
  19. int size;
  20. }Queue;
  21. // 初始化队列
  22. void QueueInit(Queue* q);
  23. // 队尾人队列
  24. void QueuePush(Queue* q, QDataType data);
  25. // 队头出队列
  26. void QueuePop(Queue* q);
  27. // 获取队列头部元素
  28. QDataType QueueFront(Queue* q);
  29. // 获取队列队尾元素
  30. QDataType QueueBack(Queue* q);
  31. // 获取队列中有效元素个数
  32. int QueueSize(Queue* q);
  33. // 判空
  34. int QueueEmpty(Queue* q);
  35. // 销毁队列
  36. void QueueDestroy(Queue* q);

Queue.c

  1. #define _CRT_SECURE_NO_WARNINGS 1
  2. #define _CRT_SECURE_NO_WARNINGS 1
  3. #include"Queue.h"
  4. // 初始化队列
  5. void QueueInit(Queue* q)
  6. {
  7. assert(q);
  8. q->front = q->rear = NULL;
  9. q->size = 0;
  10. }
  11. // 队尾入队列
  12. void QueuePush(Queue* q, QDataType data)
  13. {
  14. assert(q);
  15. QNode* newnode = (QNode*)malloc(sizeof(QNode));
  16. if (newnode == NULL)
  17. {
  18. perror("malloc");
  19. exit(-1);
  20. }
  21. newnode->next = NULL;
  22. newnode->data = data;
  23. if (q->front /*= q->rear*/ == NULL)//谨记判断不要用此等格式
  24. {
  25. q->front = q->rear = newnode;
  26. }
  27. else
  28. {
  29. q->rear->next = newnode;
  30. q->rear = newnode;
  31. }
  32. q->size++;
  33. }
  34. // 队头出队列
  35. void QueuePop(Queue* q)
  36. {
  37. assert(q);
  38. assert(!QueueEmpty(q));
  39. if (q->front->next == NULL)
  40. {
  41. free(q->front);
  42. q->front = q->rear = NULL;
  43. }
  44. else
  45. {
  46. QNode* next = q->front->next;
  47. free(q->front);
  48. q->front = next;
  49. }
  50. q->size--;
  51. }
  52. // 获取队列头部元素
  53. QDataType QueueFront(Queue* q)
  54. {
  55. assert(q);
  56. assert(!QueueEmpty(q));
  57. return q->front->data;
  58. }
  59. // 获取队列队尾元素
  60. QDataType QueueBack(Queue* q)
  61. {
  62. assert(q);
  63. assert(!QueueEmpty(q));
  64. return q->rear->data;
  65. }
  66. // 获取队列中有效元素个数
  67. int QueueSize(Queue* q)
  68. {
  69. assert(q);
  70. return q->size;
  71. }
  72. // 检测队列是否为空,如果为空返回非零结果,如果非空返回0
  73. int QueueEmpty(Queue* q)
  74. {
  75. assert(q);
  76. return q->size == 0;
  77. }
  78. // 销毁队列
  79. void QueueDestroy(Queue* q)
  80. {
  81. assert(q);
  82. QNode* cur = q->front;
  83. QNode* next = NULL;
  84. while (cur)
  85. {
  86. next = cur->next;
  87. free(cur);
  88. cur = next;
  89. }
  90. cur = NULL;
  91. q->rear = NULL;
  92. }

同志们!二叉树(初阶)的知识就到这了,加油!

二叉树(初阶)阶段就到这里了;

后面博主会陆续更新;

如有不足之处欢迎来补充交流!

完结。。


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

闽ICP备14008679号