PAT MOOC dataStructure 4-1

数据结构练习 4-1 AVL 树

1. 题目:

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 ythe root of the resulting AVL tree in one line.

Sample Input 1:

5
88 70 61 96 120

Sample Output 1:

   70

 

2.题目分析:

   非常典型的AVL平衡二叉树的实现。

   根据老师提供的代码框架结构进行编程。 里面运用了递归的算法,这一点是我比较薄弱的地方。每次遇到递归头就会变大。随着递归的螺旋脑子就会越来越不清晰。呜呜

   题目的要求就是依次插入数结点,并按照左小右大的规则插入数值。

   使用InsertNode函数递归进行插入。如果数值大于当前结点数值,则递归插入到右侧子树。反之亦然。

   同时,每次插入结束后,要递归的的更改树节点高度的值,以使得上层的节点可以对比左右两子树的高度差以判别本身是否平衡。

   如果判断当前节点不平衡,因为是递归运行的程序,所以其子节点一定平衡,当前节点为第一个不平衡的节点,此时通过LL,LR,RR或者RL对当前节点进行平衡调整。

   调整的方法以LL为例。

           此时,当前节点A不平衡,且插入的节点位于左子树B的左子树C。

          首先, 将A->left(原为B)指向B->right, 完成交换。然后将B->right = A,然后返回B,此时B的右子树为A,同时B原本的右子树变为A的左子树。

          然后返回B,此时上层的指针便会指向B,同时B层平衡。如果发现此时上层又不平衡,则继续调整,直到返回Root,更新根节点。

LR则是 先对 A 的左子树B进行 RR,再将A进行LL。以保持树的平衡。

 

3.源代码:

 

#include <stdio.h>
#include <stdlib.h>

typedef struct AVLnode{
    int height;
    struct AVLnode * left;
    struct AVLnode * right;
    int data;
}tAVLnode, *pAVL;

pAVL SingleLeftRotation(pAVL T);

pAVL DoubleLeftRightRotation(pAVL T);

pAVL SingleRightRotation(pAVL T);

pAVL DoubleRightLeftRotation(pAVL T);

pAVL InsertNode(int data, pAVL T);

int GetHeight(pAVL T);

pAVL InsertNode(int data, pAVL T)
{
    if(!T)
    {
        T = (pAVL)malloc(sizeof(tAVLnode));
        T->data = data;
        T->height = 0;
        T->left = NULL;
        T->right = NULL;
    }
    else if(data < T->data)
    {
        T->left = InsertNode(data,T->left);
        if(GetHeight(T->left)-GetHeight(T->right)== 2)
        {
            if(data < T->left->data)
            {
                T=SingleLeftRotation(T);
            }
            else
            {
                T=DoubleLeftRightRotation(T);
            }
        }
    }
    else if(data > T->data)
    {
        T->right = InsertNode(data,T->right);
        if(GetHeight(T->left)-GetHeight(T->right) == -2)
        {
            if(data > T->right->data)
            {
                T=SingleRightRotation(T);
            }
            else
            {
                T=DoubleRightLeftRotation(T);
            }
        }
    }
    T->height = (GetHeight(T->left)>=GetHeight(T->right))?GetHeight(T->left)+1:GetHeight(T->right)+1;
    
    return T;    
}

pAVL SingleLeftRotation(pAVL T)
{
    pAVL B = T->left;
    T->left = B->right;
    B->right = T;
    T->height = (GetHeight(T->left)>=GetHeight(T->right))?GetHeight(T->left)+1:GetHeight(T->right)+1;
    B->height = (GetHeight(B->left)>=GetHeight(B->right))?GetHeight(B->left)+1:GetHeight(B->right)+1;
    return B;
}

pAVL DoubleLeftRightRotation(pAVL T)
{
    T->left = SingleRightRotation(T->left);
    return SingleLeftRotation(T);
}

pAVL SingleRightRotation(pAVL T)
{
    pAVL B = T->right;
    T->right = B->left;
    B->left = T;
    T->height = (GetHeight(T->left)>=GetHeight(T->right))?GetHeight(T->left)+1:GetHeight(T->right)+1;
    B->height = (GetHeight(B->left)>=GetHeight(B->right))?GetHeight(B->left)+1:GetHeight(B->right)+1;
    return B;
}

pAVL DoubleRightLeftRotation(pAVL T)
{
    T->right = SingleLeftRotation(T->right);
    return SingleRightRotation(T);
}

int GetHeight(pAVL T)
{
    if(!T)
    {
        return -1;
    }
    else
    {
        return T->height;
    }
}

int main()
{
    int nodeSum;
    int data;
    int i;
    pAVL Root = NULL;
    
    scanf("%d", &nodeSum);
    
    for(i=0;i<nodeSum;i++)
    {
        scanf("%d",&data);
        Root = InsertNode(data,Root);
    }
    printf("%d",Root->data);
}

 

 

 

posted @ 2014-12-30 19:55  sjtubear  阅读(268)  评论(0编辑  收藏  举报