判断二叉树是否是完全二叉树

来源:互联网 发布:海康威视网络设置方法 编辑:程序博客网 时间: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
原创粉丝点击