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

点:二叉树

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

剑指offer面试题39引申

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

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

两个解法的代码:

#include <random>
#include <iostream>


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

template<class T> class Btree {
    Node<T> *root;

public:
    Btree():root(nullptr){}
    void Free (Node<T> *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<T>(val);
        } else {
            Node<T> *cur = root;
            while (cur) {
                if (cur->val > val) {
                    if (cur->lchild) {
                        cur = cur->lchild;
                    } else {
                        Node<T> *newnode = new Node<T>(val);
                        cur->lchild = newnode;
                    }
                } else if (cur->val < val) {
                    if (cur->rchild) {
                        cur = cur->rchild;
                    } else {
                        Node<T> *newnode = new Node<T>(val);
                        cur->rchild = newnode;
                    }
                } else {
                    break;
                }
            }
        }
    }

    void Pre (Node<T> *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<T> *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<T> *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<int> 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;
}
    原文作者:AVL树
    原文地址: https://blog.csdn.net/u010246947/article/details/77366528
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞