04-树5 Root of AVL Tree
此题要求找出AVL树的根节点,只需将课上讲的AVL树的基本操作运用起来即可。重点就是AVL树各种旋转以及插入新元素时的操作过程。
#include <stdio.h> #include <stdlib.h> typedef struct AVLNode *AVLTree; struct AVLNode{ AVLTree Left; AVLTree Right; int Data; int Height; }; int Max(int a, int b) { return a > b ? a : b; } int GetHeight(AVLTree T) { if(!T) return 0; else return T->Height; } AVLTree SingleLeftRotation(AVLTree A) { //A必须有一个左子节点B //将A与B做单左旋,更新A与B的高度,返回新的根节点B AVLTree B = A->Left; A->Left = B->Right; B->Right = A; A->Height = Max(GetHeight(A->Left), GetHeight(A->Right)) + 1; B->Height = Max(GetHeight(B->Left), A->Height) + 1; return B; } AVLTree SingleRightRotation(AVLTree A) { AVLTree B = A->Right; A->Right = B->Left; B->Left = A; A->Height = Max(GetHeight(A->Left), GetHeight(A->Right)) + 1; B->Height = Max(GetHeight(B->Right), A->Height) + 1; return B; } AVLTree DoubleLeftRightRotation(AVLTree A) { //A必须有一个左子节点B,且B必须有一个右子节点C //将A、B与C做两次单旋,返回新的根节点C A->Left = SingleRightRotation(A->Left); //B与C做右单旋,C被返回 return SingleLeftRotation(A); //A与C做左单旋,C被返回 } AVLTree DoubleRightLeftRotation(AVLTree A) { A->Right = SingleLeftRotation(A->Right); return SingleRightRotation(A); } AVLTree Insert(AVLTree T, int X) { if(!T){ //插入空树,新建包含一个结点的树 T = (AVLTree)malloc(sizeof(struct AVLNode)); T->Data = X; T->Height = 0; T->Left = T->Right = NULL; } else if(X < T->Data){ //插入T的左子树 T->Left = Insert(T->Left, X); //如果需要左旋 if(GetHeight(T->Left) - GetHeight(T->Right) == 2) if(X < T->Left->Data) //X在“左左上” T = SingleLeftRotation(T); //左单旋 else //X在“左右”上,LR旋 T = DoubleLeftRightRotation(T); } else if(X > T->Data){ T->Right = Insert(T->Right, X); if(GetHeight(T->Left) - GetHeight(T->Right) == -2) if(X > T->Right->Data) T = SingleRightRotation(T); else T = DoubleRightLeftRotation(T); } T->Height = Max(GetHeight(T->Left), GetHeight(T->Right)) + 1; return T; } int main(int argc, char const *argv[]) { int N, i, data; AVLTree T; scanf("%d", &N); for(i = 0; i < N; i++){ scanf("%d", &data); T = Insert(T, data); } printf("%d\n", T->Data); return 0; }