判断一个二叉树是否是AVL树

点:二叉树


题意:判断一个二叉树是否是AVL树,即二叉树任意一个节点的左右子树深度之差不得大于1

剑指offer面试题39引申


思路:和算二叉树的深度一样,依然按后序,然后依次求深度,同时传入一个bool变量入函数栈,每个节点只要发现左右子树深度超过1,就可以说明已经不是avl树了。


在剑指offer中还有一种更高效的解法,它虽然也依赖树的深度,但不是以算深度为主导,而是在每次发现深度差超过1时,即发现已经不是avl树时,便给上级递归返回这个结果,上级发现下层左或右节点已经非avl时,就不会再继续去算另一个节点的情况了,而是直接返回这个非avl的结果到它的递归上一级。相比上面的算法,这个算法在某些情况下确实节省了很多不必要的二叉树深度计算。


两个解法的代码:

#include 
#include 


template struct Node {
    T val;
    Node *lchild;
    Node *rchild;
    Node(T _val):val(_val), lchild(nullptr), rchild(nullptr) {}
};

template class Btree {
    Node *root;

public:
    Btree():root(nullptr){}
    void Free (Node *cur) {
        if (cur) {
            Free(cur->lchild);
            Free(cur->rchild);
            delete cur;
            cur = nullptr;
        }
    }
    ~Btree () {
        Free(root);
    }

    void Add (int val) {
        if (!root) {
            root = new Node(val);
        } else {
            Node *cur = root;
            while (cur) {
                if (cur->val > val) {
                    if (cur->lchild) {
                        cur = cur->lchild;
                    } else {
                        Node *newnode = new Node(val);
                        cur->lchild = newnode;
                    }
                } else if (cur->val < val) {
                    if (cur->rchild) {
                        cur = cur->rchild;
                    } else {
                        Node *newnode = new Node(val);
                        cur->rchild = newnode;
                    }
                } else {
                    break;
                }
            }
        }
    }

    void Pre (Node *cur) {
        if (cur) {
            std::cout << cur->val << "\t";
            Pre(cur->lchild);
            Pre(cur->rchild);
        }
    }
    
    void pre () {
        Pre(root);
        std::cout << std::endl;
    }

    bool Judge2 (Node *cur, int *depth) {
        if (cur) {
            int left, right;
            if (Judge2(cur->lchild, &left) && Judge2(cur->rchild, &right)) {
                *depth = 1 + ((left > right)?left:right);
                if (left - right > 1 || right - left > 1) {
                    return false;
                } else {
                    return true;
                }
            } else {
                return false;
            }
        } else {
            *depth = 0;
            return true;
        }
    }
    
    bool judge_if_avl2 () {
        int depth = 1;
        return Judge2(root, &depth);
    }
    
    int Judge (Node *cur, int dp, bool &res) {
        if (cur) {
            int ld = Judge(cur->lchild, dp + 1, res);
            int rd = Judge(cur->rchild, dp + 1, res);
            if (ld - rd > 1 || rd - ld > 1) {
                res = false;
            }
            return (ld > rd)?ld:rd;
        } else {
            return dp - 1;
        }
    }
    
    bool judge_if_avl () {
        bool res = true;
        Judge(root, 1, res);
        return res;
    }
};

int main () {
    Btree bt;
    std::random_device rd;
    for (int i = 0; i < 7; i++) {
        bt.Add(rd() % 100);
    }
    bt.pre();
    std::cout << bt.judge_if_avl() << std::endl;
    std::cout << bt.judge_if_avl2() << std::endl;
    return 0;
}


你可能感兴趣的:(二叉树)