平衡二叉树又叫AVL(人名的简称)树,在不同的教材中,对AVL树的定义是不同的。考研指定的教材是严奶奶编写的教材,我们来看看该书上(P233)是如何定义的:
AVL树或者是一棵空树,或者满足以下条件:
(1). 其左子树和右子树都为AVL树
(2). 左子树和右子树的高度之差的绝对值不超过1
然而,有很多教材不是这么定义的,而是把AVL树定义在BST基础之上,比如在李春葆的2012版的《数据结构联考辅导教程》中(P174)就定义在BST基础之上,但是,该书第184页码的judgeAVL函数就没有考虑AVL树的BST性质。
在这里,我们依然按照严奶奶的定义来办事。
下面对AVL树进行判定:
#include <iostream>
using namespace std;
typedef struct node
{
int key;
struct node *lChild, *rChild;
}Node;
// 生成一个结点
Node *createNode(int i)
{
Node * q = new Node;
q->lChild = NULL;
q->rChild = NULL;
q->key = i;
return q;
}
// 非AVL树
Node *createNotAVLTree()
{
Node *p1 = createNode(1);
Node *p2 = createNode(2);
Node *p3 = createNode(3);
Node *p4 = createNode(4);
p1->lChild = p2;
p1->rChild = NULL;
p2->lChild = p3;
p2->rChild = p4;
p3->lChild = p3->rChild = NULL;
p4->lChild = p4->rChild = NULL;
return p1;
}
// AVL树
Node *createAVLTree()
{
Node *p1 = createNode(1);
Node *p2 = createNode(2);
Node *p3 = createNode(3);
Node *p4 = createNode(4);
p1->lChild = p2;
p1->rChild = p4;
p2->lChild = p3;
p2->rChild = NULL;
p3->lChild = p3->rChild = NULL;
p4->lChild = p4->rChild = NULL;
return p1;
}
void AVLTest(Node *T, int &isAVL, int &height)
{
int bLeft, bRight;
int hLeft, hRight;
if(NULL == T)
{
height = 0;
isAVL = 1;
}
else if(NULL == T->lChild && NULL == T->lChild)
{
height = 1;
isAVL = 1;
}
else
{
AVLTest(T->lChild, bLeft, hLeft);
AVLTest(T->rChild, bRight, hRight);
height = (hLeft < hRight ? hRight : hLeft) + 1; // 树高
if(abs(hLeft - hRight) < 2) // AVL树的要求
{
isAVL = bLeft & bRight; // 同时为1才是AVL树
}
else
{
isAVL = 0;
}
}
}
bool isAVLTree(Node *T)
{
int isAVL = 0;
int height = 0;
AVLTest(T, isAVL, height);
if(1 == isAVL)
return true;
return false;
}
void printJudge(Node *T)
{
if(isAVLTree(T))
cout << "yes" << endl;
else
cout << "no" << endl;
}
int main()
{
Node *T = NULL;
printJudge(T); // yes
T = createNotAVLTree();
printJudge(T); // no
T = createAVLTree();
printJudge(T); // yes
return 0;
}
上面的程序比较巧妙,需要好好体会。另外,需要感叹一下:在写程序的时候,经常把lChild和rChild写错(写反),所以,在以后的程序中,尽量把lChild写成leftChild, 把rChild写成rightChild.