04-树5 Root of AVL Tree

来源:互联网 发布:丸子网络 编辑:程序博客网 时间:2024/06/14 00:33
/*=====================================================================================#       COPYRIGHT NOTICE#       Copyright (c) 2016##       @Author       :Zehao Wang#       @Email         :zehaowang@163.com#       @from            :https://pta.patest.cn/pta/test/1342/exam/4/question/20492#       @Last modified         :2016-12-3#       @Description    :求平衡二叉树根节点(涉及到旋转)========================================================================================*/#include <stdio.h>#include<stdlib.h>typedef struct AvlNode* AvlTree;struct AvlNode{    int data;    AvlTree left;    AvlTree right;    int height;};//求两数最大值int Max(int a, int b){    int i = (a > b ? a : b);    return i;}//求节点高度。节点为NULL则高度为-1,没有左右儿子的节点高度为0int height(AvlTree Tree){    if (!Tree)        return -1;    else        return Tree->height;}//左单旋AvlTree singleRotateWithLeft(AvlTree K1){    AvlTree K2 = K1->left;     K1->left=K2->right;     K2->right = K1;     K1->height = Max(height(K1->left), height(K1->right))+1;     K2->height = Max(height(K2->left), height(K1))+1;     return K2;}//右单旋AvlTree singleRotateWithRight(AvlTree K1){    AvlTree K2 = K1->right;    K1->right = K2->left;    K2->left = K1;    K1->height=Max(height(K1->left), height(K1->right))+1;    K2->height= Max(height(K1), height(K2->right))+1;    return K2;}//左双旋AvlTree doubleRotateWithLeft(AvlTree K1){    K1->left = singleRotateWithRight(K1->left);    return  singleRotateWithLeft(K1);}//右双旋AvlTree doubleRotateWithRight(AvlTree K1){    K1->right = singleRotateWithLeft(K1->right);    return singleRotateWithRight(K1);}//插入函数,每插入一个节点,都要调整一次平衡AvlTree Insert(int x, AvlTree Tree){    if (Tree == NULL)    {        Tree = (AvlTree)malloc(sizeof(struct AvlNode));        Tree->data = x;        Tree->left = NULL;        Tree->right = NULL;        Tree->height = 0;    }    else    {        if (x < Tree->data)        {            Tree->left=Insert(x, Tree->left);            if (height(Tree->left)- height(Tree->right) == 2)            {                if (x < Tree->left->data)                    Tree = singleRotateWithLeft(Tree);                else if (x > Tree->left->data)                    Tree = doubleRotateWithLeft(Tree);            }        }        else if (x > Tree->data)        {            Tree->right = Insert(x, Tree->right);            if (height(Tree->right) - height(Tree->left) == 2)            {                if (x > Tree->right->data)                    Tree = singleRotateWithRight(Tree);                else if(x<Tree->right->data)                    Tree= doubleRotateWithRight(Tree);            }        }    }    Tree->height = Max(height(Tree->left), height(Tree->right)) + 1;    return Tree;}int main(void){    int N;    int x;    scanf("%d", &N);    AvlTree Tree;    Tree = NULL;    for (int i = 0; i < N; i++)    {        if (scanf("%d", &x) == 1)        Tree = Insert(x, Tree);    }    printf("%d",Tree->data);}/*=======================================================================================注:最开始学旋转的时候很难理解二叉树的旋转究竟是一个怎样的流程。后来偶然看到一篇讲解二叉树插入旋转的文章之后,茅塞顿开。文章链接:http://www.2cto.com/kf/201606/514183.html文章很重视思考的过程。从一开始为什么要旋转二叉树讲起,不断深入,最后一步步引到二叉树的不同旋转方式。其实,所有的知识产物都是为了解决问题而被人不断思考,改进出来的,绝非空穴来风。但现在大多数的教科书都会把人的思考过程隐去,只告诉你结论,只告诉你要掌握住什么。而有意无意的忽略了知识从无到有产生的过程。或许思考过程并不如知识本身来的直接,但其中所蕴含的思考方式却值得后人的借鉴,也更有利于知识被更好的理解。========================================================================================*/
0 0
原创粉丝点击