平衡二叉树又叫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.