Data structure notes--common binary tree classification and judgment implementation

Table of contents

1--Search the binary tree

2--complete binary tree

3--Balanced binary tree

4--full binary tree


1--Search the binary tree

Search the nature of the binary tree: the node values ​​of the left subtree are smaller than the root node, and the node values ​​of the right subtree are larger than the root node;

How to judge a binary tree is a search binary tree?

Main idea:

        Recursively judge whether it is a search binary tree from bottom to top, and return the corresponding minimum and maximum values ​​while returning the judgment result;

#include <iostream>
#include <climits>

struct TreeNode {
     int val;
     TreeNode *left, *right;
     TreeNode() : val(0), left(nullptr), right(nullptr) {}
     TreeNode(int x) : val(x), right(nullptr) {}
};

struct ReturnType{
    bool isBST = true;
    int max = 0;
    int min = 0;
    ReturnType(bool ib, int ma, int mi) : isBST(ib), max(ma), min(mi){}
};

class Solution {
public:
    bool isBST(TreeNode *root){
        ReturnType res = dfs(root);
        return res.isBST;
    }

    ReturnType dfs(TreeNode *root){
        // 初始化最大值为整型最小值,最小值为整型最大值
        if(root == NULL) return ReturnType(true, INT_MIN, INT_MAX); 
        ReturnType left = dfs(root->left);
        ReturnType right = dfs(root->right);

        bool isBST = true;
        if(!left.isBST || !right.isBST || left.max >= root->val || right.min <= root->val){
            isBST = false;
        }
        int min = std::min(std::min(root->val, left.min), std::min(root->val, right.min)); 
        int max = std::max(std::max(root->val, left.max), std::max(root->val, right.max));
        return ReturnType(isBST, max, min);
    }
};

int main(int argc, char *argv[]){
    TreeNode *Node1 = new TreeNode(4);
    TreeNode *Node2 = new TreeNode(2);
    TreeNode *Node3 = new TreeNode(6);
    TreeNode *Node4 = new TreeNode(1);
    TreeNode *Node5 = new TreeNode(3);
    TreeNode *Node6 = new TreeNode(5);
    TreeNode *Node7 = new TreeNode(7);


    Node1->left = Node2;
    Node1->right = Node3;
    Node2->left = Node4;
    Node2->right = Node5;
    Node3->left = Node6;
    Node3->right = Node7;


    Solution S1;
    bool res = S1.isBST(Node1);
    if (res) std::cout << "true" << std::endl;
    else std::cout << "false" << std::endl;
    return 0;
}

2--complete binary tree

How to judge a binary tree is a complete binary tree?

Main idea:

        Hierarchically traverse the nodes of the binary tree. When encountering the first node (its left and right sons are not complete) to mark, all nodes encountered in the future should be leaf nodes. When encountering a node that is not a leaf node, return false to indicate that the binary tree is not complete binary tree;

#include <iostream>
#include <queue>

struct TreeNode {
     int val;
     TreeNode *left, *right;
     TreeNode() : val(0), left(nullptr), right(nullptr) {}
     TreeNode(int x) : val(x), right(nullptr) {}
};

class Solution {
public:
    bool isCBT(TreeNode *root){
        if(root == NULL) return true;
        std::queue<TreeNode*> q;
        q.push(root);
        bool flag = false; 
        while(!q.empty()){ // 层次遍历
            TreeNode *cur = q.front();
            q.pop();
            if(cur->left != NULL) q.push(cur->left);
            if(cur->right != NULL) q.push(cur->right);
       
            if( // 标记节点后,还遇到了不是叶子节点的节点,返回false
                (flag == true && (cur->left != NULL || cur->right != NULL)) 
                || // 左儿子为空,右儿子不为空,返回false
                (cur->left == NULL && cur->right != NULL)
            ) return false;
            
            // 遇到第一个左右儿子不双全的节点进行标记
            if(cur->left == NULL || cur->right == NULL) flag = true;
        }
        return true;
    }
};

int main(int argc, char *argv[]){
    TreeNode *Node1 = new TreeNode(1);
    TreeNode *Node2 = new TreeNode(2);
    TreeNode *Node3 = new TreeNode(3);
    TreeNode *Node4 = new TreeNode(4);
    TreeNode *Node5 = new TreeNode(5);
    TreeNode *Node6 = new TreeNode(6);
    TreeNode *Node7 = new TreeNode(7);
    TreeNode *Node8 = new TreeNode(8);
    TreeNode *Node9 = new TreeNode(9);
    TreeNode *Node10 = new TreeNode(10);
    TreeNode *Node11 = new TreeNode(11);
    TreeNode *Node12 = new TreeNode(12);

    Node1->left = Node2;
    Node1->right = Node3;
    Node2->left = Node4;
    Node2->right = Node5;
    Node3->left = Node6;
    Node3->right = Node7;
    Node4->left = Node8;
    Node4->right = Node9;
    Node5->left = Node10;
    Node5->right = Node11;
    Node6->left = Node12;

    Solution S1;
    bool res = S1.isCBT(Node1);
    if (res) std::cout << "true" << std::endl;
    else std::cout << "false" << std::endl;
    return 0;
}

3--Balanced binary tree

Balanced binary tree requirements: the height difference between the left subtree and the right subtree <= 1;

How to judge that a binary tree is a balanced binary tree?

Main idea:

        Recursively judge whether it is a balanced binary tree from bottom to top, and return the corresponding depth while returning the judgment result;

#include <iostream>
#include <queue>

struct TreeNode {
     int val;
     TreeNode *left, *right;
     TreeNode() : val(0), left(nullptr), right(nullptr) {}
     TreeNode(int x) : val(x), right(nullptr) {}
};

struct ReturnType{
    bool isbalanced = true;
    int height = 0;
    ReturnType(bool ib, int h) : isbalanced(ib), height(h) {}
};

class Solution {
public:
    bool isBalanced(TreeNode *root){
        ReturnType res = dfs(root);
        return res.isbalanced;
    }

    ReturnType dfs(TreeNode *root){
        if(root == NULL) return ReturnType(true, 0);
        ReturnType left = dfs(root->left);
        ReturnType right = dfs(root->right);

        int cur_height = std::max(left.height, right.height) + 1; 
        
        bool cur_balanced = left.isbalanced && right.isbalanced 
            && std::abs(left.height - right.height) <= 1;

        return ReturnType(cur_balanced, cur_height);
    }

private:
    int height = 0;
};

int main(int argc, char *argv[]){
    TreeNode *Node1 = new TreeNode(1);
    TreeNode *Node2 = new TreeNode(2);
    TreeNode *Node3 = new TreeNode(3);
    TreeNode *Node4 = new TreeNode(4);
    TreeNode *Node5 = new TreeNode(5);
    TreeNode *Node6 = new TreeNode(6);
    TreeNode *Node7 = new TreeNode(7);
    TreeNode *Node8 = new TreeNode(8);
    TreeNode *Node9 = new TreeNode(9);
    TreeNode *Node10 = new TreeNode(10);
    TreeNode *Node11 = new TreeNode(11);
    TreeNode *Node12 = new TreeNode(12);

    Node1->left = Node2;
    Node1->right = Node3;
    Node2->left = Node4;
    Node2->right = Node5;
    Node3->left = Node6;
    Node3->right = Node7;
    Node4->left = Node8;
    Node4->right = Node9;
    Node5->left = Node10;
    Node5->right = Node11;
    Node6->left = Node12;

    Solution S1;
    bool res = S1.isBalanced(Node1);
    if (res) std::cout << "true" << std::endl;
    else std::cout << "false" << std::endl;
    return 0;
}

4--full binary tree

Judgment of full binary tree: number of nodes = 2^depth - 1;

How to judge that a binary tree is a balanced binary tree?

Main idea:

        Recursively judge whether it is a full binary tree from bottom to top, and return the corresponding depth and number of nodes while returning the judgment result;

#include <iostream>
#include <queue>

struct TreeNode {
     int val;
     TreeNode *left, *right;
     TreeNode() : val(0), left(nullptr), right(nullptr) {}
     TreeNode(int x) : val(x), right(nullptr) {}
};

struct ReturnType{
    bool isFCT = true;
    int height = 0;
    int nodes = 0;
    ReturnType(bool ib, int h, int n) : isFCT(ib), height(h), nodes(n){}
};

class Solution {
public:
    bool isFCT(TreeNode *root){
        ReturnType res = dfs(root);
        return res.isFCT;
    }

    ReturnType dfs(TreeNode *root){
        if(root == NULL) return ReturnType(true, 0, 0);
        ReturnType left = dfs(root->left);
        ReturnType right = dfs(root->right);
        bool isFCT = true;
        int cur_nodes = left.nodes + right.nodes + 1;
        int cur_height = std::max(left.height, right.height) + 1;
        if(!left.isFCT || !right.isFCT || (1<<cur_height) - 1 != cur_nodes){
            isFCT = false;
        }
        return ReturnType(isFCT, cur_height, cur_nodes);
    }
};

int main(int argc, char *argv[]){
    TreeNode *Node1 = new TreeNode(1);
    TreeNode *Node2 = new TreeNode(2);
    TreeNode *Node3 = new TreeNode(3);
    TreeNode *Node4 = new TreeNode(4);
    TreeNode *Node5 = new TreeNode(5);
    TreeNode *Node6 = new TreeNode(6);
    TreeNode *Node7 = new TreeNode(7);
    TreeNode *Node8 = new TreeNode(8);
    TreeNode *Node9 = new TreeNode(9);
    TreeNode *Node10 = new TreeNode(10);
    TreeNode *Node11 = new TreeNode(11);
    TreeNode *Node12 = new TreeNode(12);

    Node1->left = Node2;
    Node1->right = Node3;
    Node2->left = Node4;
    Node2->right = Node5;
    Node3->left = Node6;
    Node3->right = Node7;
    Node4->left = Node8;
    Node4->right = Node9;
    Node5->left = Node10;
    Node5->right = Node11;
    Node6->left = Node12;

    Solution S1;
    bool res = S1.isFCT(Node1);
    if (res) std::cout << "true" << std::endl;
    else std::cout << "false" << std::endl;
    return 0;
}

Guess you like

Origin blog.csdn.net/weixin_43863869/article/details/132247293