04-树5 Root of AVL Tree 分数 25 作者 陈越 单位 浙江大学
An AVL tree is a self-balancing binary search tree. In an AVL tree, the heights of the two child subtrees of any node differ by at most one; if at any time they differ by more than one, rebalancing is done to restore this property. Figures 1-4 illustrate the rotation rules.
Now given a sequence of insertions, you are supposed to tell the root of the resulting AVL tree.
Input Specification:
Each input file contains one test case. For each case, the first line contains a positive integer N (≤20) which is the total number of keys to be inserted. Then N distinct integer keys are given in the next line. All the numbers in a line are separated by a space.
Output Specification:
For each test case, print the root of the resulting AVL tree in one line.
Sample Input 1:
5
88 70 61 96 120
Sample Output 1:
70
Sample Input 2:
7
88 70 61 96 120 90 65
Sample Output 2:
88
代码长度限制:16 KB 时间限制:400 ms 内存限制:64 MB
题目解析:
主要考察平衡二叉树的插入问题。若插入元素后不平衡,一共将有四种情况调整为平衡,即左单旋、右单旋、左-右双旋、右-左双旋,如下图所示。
参考代码:
# include<stdio.h>
# include<stdlib.h>typedef int ElementType;typedef struct TreeNode* BinTree;
struct TreeNode{ElementType data;BinTree Left;BinTree Right;
};BinTree SingleLeftRotation(BinTree Tree);
BinTree SingleRightRotation(BinTree Tree);
BinTree DoubleLRRotation(BinTree Tree);
BinTree DoubleRLRotation(BinTree Tree);
ElementType GetHeight(BinTree Tree);
ElementType Max(ElementType a, ElementType b);
BinTree InsertBinTree(BinTree Tree,ElementType X);int main(){// 接收结点个数int N;scanf("%d",&N);// 创建一棵空平衡二叉树BinTree Tree = NULL;// 向平衡二叉树中插入结点int i,X;for(i=0;i<N;i++){scanf("%d",&X);Tree = InsertBinTree(Tree,X);}// 输出根结点数据printf("%d",Tree->data);return 0;
}// 向平衡二叉树中插入元素,并返回插入后的根结点
BinTree InsertBinTree(BinTree Tree,ElementType X){// 如果是空树,则建树并返回if(Tree==NULL){Tree = (BinTree)malloc(sizeof(struct TreeNode));Tree->data = X;Tree->Left = Tree->Right = NULL;return Tree; }// 递归插入 if(X<Tree->data){// 递归插入左子树Tree->Left = InsertBinTree(Tree->Left,X);// 判读是否平衡 if(GetHeight(Tree->Left)-GetHeight(Tree->Right)>1){if(X>Tree->Left->data){// 左-右双旋Tree = DoubleLRRotation(Tree); }else{// 左单旋Tree = SingleLeftRotation(Tree); }} }else{// 递归插入右子树Tree->Right = InsertBinTree(Tree->Right,X);// 判读是否平衡 if(GetHeight(Tree->Right)-GetHeight(Tree->Left)>1){if(X<Tree->Right->data){// 右-左双旋Tree = DoubleRLRotation(Tree); }else{// 右单旋Tree = SingleRightRotation(Tree); }} }return Tree;
}// 左单旋,并返回旋转后的根结点
BinTree SingleLeftRotation(BinTree Tree){// 进行旋转 BinTree Root = Tree->Left;Tree->Left = Root->Right;Root->Right = Tree;return Root;
}// 右单旋,并返回旋转后的根结点
BinTree SingleRightRotation(BinTree Tree){// 进行旋转 BinTree Root = Tree->Right;Tree->Right = Root->Left;Root->Left = Tree;return Root;
}// 左-右双旋,并返回旋转后的根结点
BinTree DoubleLRRotation(BinTree Tree){// 先右旋再左旋 Tree->Left = SingleRightRotation(Tree->Left);BinTree Root = SingleLeftRotation(Tree);return Root;
} // 右-左双旋,并返回旋转后的根结点
BinTree DoubleRLRotation(BinTree Tree){// 先左旋再右旋Tree->Right = SingleLeftRotation(Tree->Right);BinTree Root = SingleRightRotation(Tree);return Root; } // 递归获取树高
ElementType GetHeight(BinTree Tree){if(Tree==NULL)return 0;else return Max(GetHeight(Tree->Left),GetHeight(Tree->Right))+1;
} // 返回两者中的较大者
ElementType Max(ElementType a, ElementType b){return a>b?a:b;
}