判断二叉树是否是完全二叉树
来源:互联网 发布:海康威视网络设置方法 编辑:程序博客网 时间:2024/06/04 18:06
1. 问题.
判断二叉树是否为完全二叉树。
完全二叉树的定义是,前n-1层都是满的,第n层如有空缺,则是缺在右边,即第n层的最右边的节点,它的左边是满的,右边是空的。
2.以3层二叉树为例,以下情况为完全二叉树
3. 原理
这个问题的描述已经提示了解法,采用广度优先遍历,从根节点开始,入队列,如果队列不为空,循环。
遇到第一个没有左儿子或者右儿子的节点,设置标志位,如果之后再遇到有左/右儿子的节点,那么这不是一颗完全二叉树。
即一旦找一个不含有子节点或者只含有一个左子节点之后,那么后续的所有节点都必须是叶子节点。否则,该树就不是完全二叉树。
4. 方法一
//二叉树结点定义typedef struct Node{int data;struct Node* left;struct Node* right;}Node;//实现广度遍历需要队列Queue<Node*> queue;//第n层最右节点标志bool leftMost = false;bool ProcessChild(Node* child){if (child){if (!leftMost){queue.push(child);}else{return false;}}else{leftMost = true;}return true;}bool IsCompleteBinaryTree(Node* root){//空树也是完全二叉树if (!root)return true;//首先根节点入队列queue.push(root);while(!queue.empty()){Node* node = queue.pop();//处理左节点if (!ProcessChild(node->left))return false;//处理右节点if (!ProcessChild(node->right))return false;}//广度优先遍历完毕,此乃完全二叉树return true;}
5.方法二
1.#include <stdlib.h>2. #include <stdio.h>3.4. class TreeNode{ 5. public:6. int value;7. TreeNode *left;8. TreeNode *right;9. TreeNode(int v) : value(v) {10. left = NULL;11. right = NULL;12. }13. ~TreeNode() {14. if (left != NULL) {15. delete left;16. left = NULL;17. }18. if (right != NULL) {19. delete right;20. right = NULL;21. }22. }23. };24. 25. struct QueueNode {26. TreeNode *data;27. QueueNode *next;28. };29. 30. //用链表的方式实现队列 31. class Queue {32. private:33. QueueNode *head; //队列的投指针 34. QueueNode *tail; //队列的尾指针 35. public:36. Queue()37. {38. head = NULL;39. tail = NULL;40. }41. void enqueue(TreeNode *node) { //入队列 42. QueueNode *q = new QueueNode();43. q->data = node;44. q->next = NULL;45. if(head == NULL) {46. head = q;47. tail = q;48. } else {49. tail->next = q;50. tail = q;51. }52. }53. //判断队列是否是空 54. bool isEmpty(){55. return head == NULL;56. }57. //出队列 58. TreeNode * dequeue(){59. if(head == NULL) return NULL;//如果当前队列是空,直接返回null. 60. QueueNode *p = head;61. TreeNode *ptree = p->data;62. head = head->next;63. if (head==NULL) { //如果出队列之后,队列为空了,则修改tail为空 64. tail == NULL;65. }66. p->next = NULL;67. delete p; //删除队列节点 68. return ptree;69. }70. ~Queue(){71. QueueNode *p = head, *q;72. while(p != NULL) {73. q = p;74. p = p->next;75. delete q;76. }77. }78. };79. /*80. 判断一个二叉树是否是完全二叉树 81. 广度优先搜索整个二叉树,一旦找一个节点只不含有子节点或者子含有一个左子节点,82. 那么后续的所有节点都必须是叶子节点。否则,该树就不是完全二叉树。83. */ 84. bool isCompBinTree(TreeNode *root) 85. {86. 87. if(root == NULL) return true;88. Queue qu;89. bool last = false; //判断当前是否已经找到了第一个不含有两个子节点的节点。 90. bool isCompBTree = true;91. TreeNode *p;92. qu.enqueue(root);93. while( ! qu.isEmpty()) {94. p = qu.dequeue();95. if(! last) { //前面所有的节点都含有两个子节点 96. if (p->left != NULL && p->right !=NULL) { //当前节点也含有两个子节点 97. qu.enqueue(p->left);98. qu.enqueue(p->right);99. } else if (p->left != NULL && p->right==NULL) { //当前节点只含有左子节点,则在其后面的所有节点都必须是叶子节点 100. last = true;101. qu.enqueue(p->left);102. } else if (p->left == NULL && p->right!=NULL) { //当前节点只含有右子节点,该树不是完全的。 103. last = true;104. isCompBTree = false;105. break;106. } else { //当前节点不含有任何的子节点。 107. last = true;108. }109. } 110. else 111. {112. //已经找到了第一个不含有两个子节点的节点,当前扫描的节点必须是叶子节点。 113. if ( p->left!=NULL || p->right != NULL) {114. isCompBTree = false;115. break;116. }117. }118. }119. if (isCompBTree) {120. printf("是完全二叉树.\n");121. } else {122. printf("不是完全二叉树.\n");123. }124. return isCompBTree;125. }126. /*127. 1 1128. 2 3 2 3129. 4 5 4 5 6130. 131. 132. */133. void clear(TreeNode *ele[], int n) {134. for(int i=0; i<n; i++) {135. ele[i]->left = NULL;136. ele[i]->right = NULL;137. }138. }139. int main()140. {141. TreeNode *ele[10];142. TreeNode *root, *p, *q;143. for(int i=0; i<10; i++) {144. ele[i] = new TreeNode(i+1);145. }146. 147. printf("Case 1: ");148. root = ele[0];149. root->left = ele[1]; root->right=ele[2];150. root->left->left=ele[3]; root->left->right=ele[4];151. isCompBinTree(root);152. 153. printf("Case 2: ");154. clear(ele, 10);155. root = ele[0];156. root->left = ele[1]; root->right=ele[2];157. root->left->right=ele[3]; root->right->left=ele[4]; root->right->right=ele[5];158. isCompBinTree(root);159. 160. /*161. 1162. */163. printf("Case 3: ");164. clear(ele, 10);165. root = ele[0];166. isCompBinTree(root);167. 168. /*169. 1170. 2171. 3172. */173. printf("Case 4: ");174. clear(ele, 10);175. root = ele[0];176. root->left = ele[1];177. root->left->left = ele[2];178. isCompBinTree(root);179. 180. /*181. 1182. 2183. */184. printf("Case 5: ");185. clear(ele, 10);186. root = ele[0];187. root->left = ele[1];188. isCompBinTree(root);189. 190. /*191. 1192. 2 3193. 4 5194. */ 195. printf("Case 6: ");196. clear(ele, 10);197. root = ele[0];198. root->left = ele[1]; root->right=ele[2];199. root->right->left = ele[3]; root->right->right = ele[4];200. isCompBinTree(root);201. 202. clear(ele, 10);203. for(int i=0; i<10; i++) {204. delete ele[i];205. }206. system("pause");207. return 0;208. }
参考文献:
[1]http://blog.chinaunix.net/uid-1844931-id-3047710.html 博主:liubird
[2]http://blog.csdn.net/lilypp/article/details/6158699/ 博主:lilypp
1.#include <stdlib.h>2. #include <stdio.h>3.4. class TreeNode{ 5. public:6. int value;7. TreeNode *left;8. TreeNode *right;9. TreeNode(int v) : value(v) {10. left = NULL;11. right = NULL;12. }13. ~TreeNode() {14. if (left != NULL) {15. delete left;16. left = NULL;17. }18. if (right != NULL) {19. delete right;20. right = NULL;21. }22. }23. };24. 25. struct QueueNode {26. TreeNode *data;27. QueueNode *next;28. };29. 30. //用链表的方式实现队列 31. class Queue {32. private:33. QueueNode *head; //队列的投指针 34. QueueNode *tail; //队列的尾指针 35. public:36. Queue()37. {38. head = NULL;39. tail = NULL;40. }41. void enqueue(TreeNode *node) { //入队列 42. QueueNode *q = new QueueNode();43. q->data = node;44. q->next = NULL;45. if(head == NULL) {46. head = q;47. tail = q;48. } else {49. tail->next = q;50. tail = q;51. }52. }53. //判断队列是否是空 54. bool isEmpty(){55. return head == NULL;56. }57. //出队列 58. TreeNode * dequeue(){59. if(head == NULL) return NULL;//如果当前队列是空,直接返回null. 60. QueueNode *p = head;61. TreeNode *ptree = p->data;62. head = head->next;63. if (head==NULL) { //如果出队列之后,队列为空了,则修改tail为空 64. tail == NULL;65. }66. p->next = NULL;67. delete p; //删除队列节点 68. return ptree;69. }70. ~Queue(){71. QueueNode *p = head, *q;72. while(p != NULL) {73. q = p;74. p = p->next;75. delete q;76. }77. }78. };79. /*80. 判断一个二叉树是否是完全二叉树 81. 广度优先搜索整个二叉树,一旦找一个节点只不含有子节点或者子含有一个左子节点,82. 那么后续的所有节点都必须是叶子节点。否则,该树就不是完全二叉树。83. */ 84. bool isCompBinTree(TreeNode *root) 85. {86. 87. if(root == NULL) return true;88. Queue qu;89. bool last = false; //判断当前是否已经找到了第一个不含有两个子节点的节点。 90. bool isCompBTree = true;91. TreeNode *p;92. qu.enqueue(root);93. while( ! qu.isEmpty()) {94. p = qu.dequeue();95. if(! last) { //前面所有的节点都含有两个子节点 96. if (p->left != NULL && p->right !=NULL) { //当前节点也含有两个子节点 97. qu.enqueue(p->left);98. qu.enqueue(p->right);99. } else if (p->left != NULL && p->right==NULL) { //当前节点只含有左子节点,则在其后面的所有节点都必须是叶子节点 100. last = true;101. qu.enqueue(p->left);102. } else if (p->left == NULL && p->right!=NULL) { //当前节点只含有右子节点,该树不是完全的。 103. last = true;104. isCompBTree = false;105. break;106. } else { //当前节点不含有任何的子节点。 107. last = true;108. }109. } 110. else 111. {112. //已经找到了第一个不含有两个子节点的节点,当前扫描的节点必须是叶子节点。 113. if ( p->left!=NULL || p->right != NULL) {114. isCompBTree = false;115. break;116. }117. }118. }119. if (isCompBTree) {120. printf("是完全二叉树.\n");121. } else {122. printf("不是完全二叉树.\n");123. }124. return isCompBTree;125. }126. /*127. 1 1128. 2 3 2 3129. 4 5 4 5 6130. 131. 132. */133. void clear(TreeNode *ele[], int n) {134. for(int i=0; i<n; i++) {135. ele[i]->left = NULL;136. ele[i]->right = NULL;137. }138. }139. int main()140. {141. TreeNode *ele[10];142. TreeNode *root, *p, *q;143. for(int i=0; i<10; i++) {144. ele[i] = new TreeNode(i+1);145. }146. 147. printf("Case 1: ");148. root = ele[0];149. root->left = ele[1]; root->right=ele[2];150. root->left->left=ele[3]; root->left->right=ele[4];151. isCompBinTree(root);152. 153. printf("Case 2: ");154. clear(ele, 10);155. root = ele[0];156. root->left = ele[1]; root->right=ele[2];157. root->left->right=ele[3]; root->right->left=ele[4]; root->right->right=ele[5];158. isCompBinTree(root);159. 160. /*161. 1162. */163. printf("Case 3: ");164. clear(ele, 10);165. root = ele[0];166. isCompBinTree(root);167. 168. /*169. 1170. 2171. 3172. */173. printf("Case 4: ");174. clear(ele, 10);175. root = ele[0];176. root->left = ele[1];177. root->left->left = ele[2];178. isCompBinTree(root);179. 180. /*181. 1182. 2183. */184. printf("Case 5: ");185. clear(ele, 10);186. root = ele[0];187. root->left = ele[1];188. isCompBinTree(root);189. 190. /*191. 1192. 2 3193. 4 5194. */ 195. printf("Case 6: ");196. clear(ele, 10);197. root = ele[0];198. root->left = ele[1]; root->right=ele[2];199. root->right->left = ele[3]; root->right->right = ele[4];200. isCompBinTree(root);201. 202. clear(ele, 10);203. for(int i=0; i<10; i++) {204. delete ele[i];205. }206. system("pause");207. return 0;208. }
0 0
- 判断一棵树是否是完全二叉树
- 判断是否是完全二叉树
- 判断是否是完全二叉树
- 判断一棵树是否是完全二叉树
- 判断是否是完全二叉树
- ~判断一棵树是否是完全二叉树~
- 判断一颗树是否是完全二叉树
- 判断一棵树是否是完全二叉树
- 判断一棵树是否是完全二叉树
- 判断一棵树是否是完全二叉树
- 判断一棵树是否是完全二叉树
- 判断一棵树是否是完全二叉树
- 判断一棵树是否是完全二叉树
- 判断一棵树是否是完全二叉树。
- 判断一个二叉树是否是完全二叉树
- 判断一棵二叉树是否是完全二叉树
- 判断二叉树是否是完全二叉树
- 判断二叉树是否是完全二叉树
- 047-148
- 使用 ARM DS-5
- jquery插件treeTable
- 软件工程(二)----结构化开发
- JAVA程序员的发展道路和最终归宿
- 判断二叉树是否是完全二叉树
- POJ 2965 The Pilots Brothers' refrigerator
- 单例模式(Singleton)
- 第九周-单步执行程序
- 如何查看JDK以及JAVA框架的源码
- 服务器编程四
- 内存分配方式
- linux用户管理笔记
- DS-5 30天试用版许可证错误Error: C9932E: Cannot obtain license for Compiler