1. 题目要求
判断一棵二叉树是否是平衡二叉树
2. 思路
AVL树的名字来源于它的发明作者G.M. Adelson-Velsky 和 E.M. Landis。AVL树是最先发明的自平衡二叉查找树(Self-Balancing Binary Search Tree,简称平衡二叉树)。
平衡二叉树定义(AVL):它或者是一颗空树,或者具有以下性质的二叉排序树:它的左子树和右子树的深度之差(平衡因子)的绝对值不超过1,且它的左子树和右子树都是一颗平衡二叉树。
一棵AVL树有如下必要条件:
- 它必须是二叉查找树(BST)。
- 每个节点的左子树和右子树的高度差至多为1。
解题思路:
根据二叉树的定义,我们可以递归遍历二叉树的每一个节点来,求出每个节点的左右子树的高度,如果每个节点的左右子树的高度相差不超过1,按照定义,它就是一颗平衡二叉树。
3. 代码
#include <iostream>
#include <limits.h>
#include <cmath>
struct Node {
int value;
Node* left;
Node* right;
Node(int value):
value(value), left(nullptr), right(nullptr) {}
};
void preOrderRecur(Node* head) {
if (head == nullptr) {
return;
}
std::cout << head->value << ",";
preOrderRecur(head->left);
preOrderRecur(head->right);
}
bool isBSTUtil(Node* head, int min, int max) {
if (head == nullptr) {
return true;
}
if (head->value <= min || head->value >= max) {
return false;
}
return isBSTUtil(head->left, min, head->value) &&
isBSTUtil(head->right, head->value, max);
}
bool isBST(Node* head) {
if (head == nullptr) {
return true;
}
return isBSTUtil(head, INT_MIN, INT_MAX);
}
int treeDepth(Node* head) {
if (head == nullptr) {
return 0;
}
int nleft = treeDepth(head->left); // left tree depth
int nright = treeDepth(head->right); // right tree depth
return nleft > nright ? nleft + 1 : nright + 1; // higher depth
}
bool isAVLHelp(Node* head) {
if (head == nullptr) {
return true;
}
int nleft = treeDepth(head->left); // left tree depth
int nright = treeDepth(head->right); // right tree depth
if (std::abs(nleft - nright) > 1) { // not blance
return false;
}
return isAVLHelp(head->left) && isAVLHelp(head->right);
}
bool isAVL(Node* head) {
if (head == nullptr) {
return true;
}
if (!isBST(head)) { // AVL tree must be BST
return false;
} else {
return isAVLHelp(head);
}
}
int main() {
Node* head1 = new Node(10);
head1->left = new Node(5);
head1->right = new Node(15);
head1->right->left = new Node(12);
head1->right->right = new Node(20);
std::cout << "==============Test1==============";
std::cout << "\npre-order: ";
preOrderRecur(head1);
bool isavl1 = isAVL(head1);
std::cout << "\n" << isavl1 << std::endl;
Node* head2 = new Node(10);
head2->left = new Node(5);
head2->right = new Node(15);
head2->right->left = new Node(6);
head2->right->right = new Node(20);
std::cout << "==============Test2==============";
std::cout << "\npre-order: ";
preOrderRecur(head2);
bool isavl2 = isAVL(head2);
std::cout << "\n" << isavl2 << std::endl;
Node* head3 = new Node(10);
head3->left = new Node(5);
head3->right = new Node(15);
head3->right->right = new Node(20);
head3->right->right->right = new Node(30);
std::cout << "==============Test3==============";
std::cout << "\npre-order: ";
preOrderRecur(head3);
bool isavl3 = isAVL(head3);
std::cout << "\n" << isavl3 << std::endl;
return 0;
}
树的结构自己画一下哈。