平衡二叉树的实现

//平衡二叉树 
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;

typedef int ElementType; 

typedef struct BinaryNode
{
    ElementType data;
    int height;
    unsigned int freq; //此节点保存的数据出现的频率 
    struct BinaryNode *left,*right;
}BinaryNode,*BinaryTree;

//求高度 
int Height(BinaryTree pNode)
{
    return pNode == NULL ? -1 : pNode->height;
}

int Max(int a, int b)
{
    return a < b ? b : a;
}

//LL型左旋
void RotateWithLeft(BinaryTree &pNode)
{ 
    BinaryTree pTemp = pNode->left; //保存节点的左子树 
    pNode->left = pTemp->right;
    pTemp->right = pNode;
     //到此树旋转完成,更新树的深度,以pNode,pTemp为节点的树的深度发生了变化; 
    pNode->height = Max(Height(pNode->left), Height(pNode->right)) + 1;
    pTemp->height = Max(Height(pTemp->left), Height(pTemp->right)) + 1;
     //pTemp为局部变量,离开作用域,变量就会销毁,因此需要返回根节点,只不过是通过引用的方式罢了;
    pNode = pTemp;
}
//RR型 
void RotateWithRight(BinaryTree &pNode)
{
    BinaryTree pTemp = pNode->right; //保存节点的右子树
    pNode->right = pTemp->left;
    pTemp->left = pNode;
     //到此树旋转完成,更新树的深度,以pNode,pTemp为节点的树的深度发生了变化; 
    pNode->height = Max(Height(pNode->left), Height(pNode->right)) + 1;
    pTemp->height = Max(Height(pTemp->left), Height(pTemp->right)) + 1;
     //pTemp为局部变量,离开作用域,变量就会销毁,因此需要返回根节点,只不过是通过引用的方式罢了; 
    pNode = pTemp;
}

//LR型 
void DoubleRotateWithLeft(BinaryTree &pNode)
{

    RotateWithRight(pNode->left);
    RotateWithLeft(pNode);
} 

//RL型 
void DoubleRotateWithRight(BinaryTree &pNode)
{

    RotateWithLeft(pNode->right);
    RotateWithRight(pNode);
} 


//左平衡处理 
void LeftBalance(BinaryTree &pNode)
{
    BinaryTree pTemp = pNode->left;
    if(Height(pTemp->left) - Height(pTemp->right) == -1)
    {
         //右子树高于左子树,在右子树插入的 
        DoubleRotateWithLeft(pNode);//LR 
    }
    else
    {
        RotateWithLeft(pNode);//LL 
    }
 } 

//右平衡处理 
void RightBalance(BinaryTree &pNode)
{
    BinaryTree pTemp = pNode->right;
    if(Height(pTemp->right) - Height(pTemp->left) == -1)
    {   //左子树比右子树高,说明在左子树插入的
        DoubleRotateWithRight(pNode); //RL 
    }
    else
    {
        RotateWithRight(pNode);  //RR 
    }
}

//插入 
void AVL_Insert(BinaryTree &pNode, ElementType key)
{
    if(NULL == pNode)
    {
        pNode = new BinaryNode;
        pNode->data = key;
        pNode->height = 0;
        pNode->freq= 1;
        pNode->left = NULL;
        pNode->right = NULL;    
    } 
    else if(key < pNode->data) //在左子树插入
    {
        AVL_Insert(pNode->left, key);
        //判断是否破坏AVL树的平衡性
        if((Height(pNode->left) - Height(pNode->right)) == 2)
        {
            LeftBalance(pNode);//左平衡处理 
        }
    }
    else if(key > pNode->data) //在右子树插入
    {
        AVL_Insert(pNode->right, key);
        //判断是否破坏AVL树的平衡性
        if((Height(pNode->right) - Height(pNode->left)) == 2)
        {
            RightBalance(pNode); //右平衡处理 
        }
    }
    else
    {
        pNode->freq++;
    }

    pNode->height = Max(Height(pNode->left), Height(pNode->right)) + 1; //更新树的高度
}

//查找 
BinaryTree AVL_Search(BinaryTree &pNode, ElementType key)
{
    if(pNode == NULL)
    {
        return NULL;
    }
    else if(key > pNode->data) 
    {
        AVL_Search(pNode->right, key);
    }
    else if(key < pNode->data)
    {
        AVL_Search(pNode->left, key);
    }
    else
    {
        return pNode;
    }
}

//删除
void AVL_Delete(BinaryTree &pNode, ElementType key) 
{
    if(pNode == NULL) //空树返回 
    {
        return ; 
    }
    if(key < pNode->data) //在左子树中查找 
    {
        AVL_Delete(pNode->left, key);

        if((Height(pNode->right) - Height(pNode->left)) == 2) //左子树删除一个节点,判断是否需要右平衡处理 
        {
            RightBalance(pNode);
        }   
    }
    else if(key > pNode->data)
    {
        AVL_Delete(pNode->right, key);

        if((Height(pNode->left) - Height(pNode->right)) == 2) //右子树删除一个节点,判断是否需要左平衡处理 
        {
            LeftBalance(pNode); //左平衡处理 
        }   
    }
    else //找到要删除的元素节点
    {
        if(pNode->left == NULL) //左子树为空 
        {
            BinaryTree pTemp = pNode;
            pNode = pNode->right; //用右孩子代替此节点 
            free(pTemp);  //释放内存 
        }
        else if(pNode->right == NULL) //右子树为空 
        {
            BinaryTree pTemp = pNode;
            pNode = pNode->left; //用左孩子代替此节点 
            free(pTemp);  //释放内存 
        }
        else //左右子树都不为空 
        {
            //一般的删除策略是左子树的最小数据 或 右子树的最小数据 代替该节点
            BinaryTree pTemp = pNode->left;
            while(pTemp->right != NULL)
            {
                pTemp = pTemp->right;
            }
            pNode->data = pTemp->data;
            AVL_Delete(pNode->left,pTemp->data);
        }
    }

    if(pNode)
    {
        pNode->height = Max(Height(pNode->left), Height(pNode->right));
    }
}

//中序遍历
void AVL_InorderPrint(BinaryTree &pRoot)
{
    if(pRoot != NULL)
    {
        AVL_InorderPrint(pRoot->left);
        cout << pRoot->data << " ";
        AVL_InorderPrint(pRoot->right);
    }   
} 

int main()
{
    BinaryTree root = NULL;
    AVL_Insert(root,3);
    AVL_Insert(root,2);  
    AVL_Insert(root,1);  
    AVL_Insert(root,4);  
    AVL_Insert(root,5);  
    AVL_Insert(root,6);  
    AVL_Insert(root,7);  
    AVL_Insert(root,16);  
    AVL_Insert(root,15);  
    AVL_Insert(root,14); 
    AVL_Insert(root,13);
    AVL_Insert(root,12);  
    AVL_Insert(root,11);  
    AVL_Insert(root,10); 
    AVL_Insert(root,8);
    AVL_Insert(root,9);

    AVL_InorderPrint(root);
    printf("\n%d\n",root->height);


    AVL_Delete(root,8);  
   // AVL_Delete(root,5);
    AVL_InorderPrint(root);

    BinaryTree k = AVL_Search(root,15);  
    if (k == NULL)  
    {  
        printf("没有查找到15\n");  
    }  
    else  
    {  
        printf("所在节点的高度:%d\n",k->height);  
        if (NULL!=k->left)  
        {  
            printf("所在节点的左孩子:%d\n",k->left->data);  
        }  
        if (NULL!=k->right)  
        {  
            printf("所在节点的右孩子:%d\n",k->right->data);  
        }  

    }
    system("pause");
    return 0;
}

















    原文作者:平衡二叉树
    原文地址: https://blog.csdn.net/ky_heart/article/details/75948306
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞