平衡二叉树的基本操作 (pat) 1066 Root of AVL Tree (25 分)

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer N (≤) 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.

#include <bits/stdc++.h>
using namespace std;
int n;
struct node{
    int v,height;
    node *lchild,*rchild;
} *root;

node* newNode(int v){
    node *Node = new node;//申请一个新的地址空间 
    Node->v = v;
    Node->height = 1;
    Node->lchild = Node->rchild = NULL;
    return Node; 
}

//返回以root为根节点的子树当前的height 
int getHeight(node *root){
    if(root == NULL) return 0;
    return root->height;
}

//更新节点root的heifht 

//由于在涉及到相应的AVL树进行相应的调整时,只有部分节点的高度发生了相应的变化,所以在进行调整时
//直接调用每个节点对应的height进行相应的更新,而不需要递归进行更新 
void updateHeight(node* root){
    //left和right中max进行相应的更新 
    root->height = max(getHeight(root->lchild),getHeight(root->rchild))+1;
} 
int getBalanceFactor(node* root){
    return getHeight(root->lchild)-getHeight(root->rchild);
}

//对AVL树调整的两个关键操作
void L(node* &root){
    node* temp = root->rchild;
    root->rchild = temp->lchild;
    temp->lchild = root;
    updateHeight(root);//注意需要从下面的节点进行相应的更新
    updateHeight(temp);
    root = temp; 
}

//右旋
void R(node* &root){
    node* temp =  root->lchild;
    root->lchild = temp->rchild;
    temp->rchild = root;
    updateHeight(root);
    updateHeight(temp);
    root = temp;
} 
 
void insert(node *&root,int v){
    //进行插入
    if(root == NULL){
        root = newNode(v);
        return;
    } 
    if(v < root->v){
        //由于插入的是左子树,所以只能导致L形开头 
        insert(root->lchild,v);
        updateHeight(root);//实际上这个高度的更新是一个递归的更新 
        if(getBalanceFactor(root) ==2){
            //需要进行相应的调整
            if(getBalanceFactor(root->lchild) == 1){
                //ll形,直接对根进行相应的右旋就行
                R(root); 
            }else if(getBalanceFactor(root->lchild) == -1){
                //LR形,先对左子树左旋,然后再右旋 
                 L(root->lchild);
                 R(root); 
            }
        } 
    }    
    else{
        insert(root->rchild,v);
        updateHeight(root);
        if(getBalanceFactor(root) == -2){
            //需要进行相应的调整
            if(getBalanceFactor(root->rchild) == -1){
                //RR形
                L(root);//直接进行左旋即可 
            }
            else if(getBalanceFactor(root->rchild) == 1){
                //RL形
                R(root->rchild);
                L(root);
            }
        }
    } 
}
int main(){
    int n;
    cin>>n;
    int tmp;
    node* root = NULL;
    for(int i=0;i<n;i++){
        cin>>tmp;
        insert(root,tmp);
    }
    cout<<root->v<<endl;
    return 0;
}

 

上一篇:二叉排序树的查找、插入、删除


下一篇:请写出在ASP.NET中常用的几种页面间传值的方法,并说出它们的特点。