数据结构--平衡二叉树

// Balanced Binary Tree.cpp : Defines the entry point for the console application.
/*-----CODE FOR FUN---------------
-------CREATED BY Dream_Whui------
-------2015-3-5-------------------------*/  
//平衡二叉树

#include "stdafx.h"
#include <iostream>
using namespace std;

#define        TRUE                     1  
#define        FALSE                    0  
#define        OK                         1  
#define        ERROR                   0  
#define        OVERFLOW           -2  
#define        INFEASIBLE           -1

#define        EQ(a,b)        (a == b)
#define        LT(a,b)        (a < b)
#define        LQ(a,b)        (a > b)

#define        LH            1            //左高
#define        EH            0            //等高
#define        RH            -1            //右高

typedef        int            KeyType;

typedef struct    ElemType        //定义结点的结构
{
    KeyType        key;
    char                name;
};

typedef struct BSTNode        //平衡二叉树
{
    ElemType        data;
    int                bf;                //结点的平衡因子
    struct BSTNode        *lchild, *rchild;//左、右孩子指针
}BSTNode, *BSTree;

void R_Rotate(BSTree &p)        //对以*p为根的二叉树作右旋处理,处理之后p指向新的树根结点,即旋转处理之前的左子树的根结点
{
    BSTree lc;
    lc = p->lchild;                    //lc指向*p的左子树根结点
    p->lchild = lc->rchild;        //lc的右子树挂接为*p的左子树
    lc->rchild = p;                    //p指向新的根结点
    p = lc;
}

void L_Rotate(BSTree &p)
{
    BSTree rc;
    rc = p->rchild;                //rc指向*p的右子树根结点
    p->rchild = rc->lchild;    //rc的左子树挂接为*p的右子树
    rc->lchild = p;
    p = rc;                            //p指向新的根结点
}

void LeftBalance(BSTree &T)//对以指针T所指结点为根的二叉树作左平衡旋转处理,算法结束时,指针T指向新的根结点
{
    BSTree lc, rd;
    lc = T->lchild;        //lc指向*T的左子树根结点
    switch(lc->bf)        //检查*T的左子树的平衡度,并做相应平衡处理
    {
        case LH:            //新的结点插入在*T的左孩子的左子树上,要做单右旋转处理
                T->bf = lc->bf = EH;
                R_Rotate(T);
                break;
        case RH:        //新的结点插入在*T的左孩子的右子树上,要做双旋处理
                rd = lc->rchild;    //rd指向*T的左孩子的右子树根
            switch(rd->bf)        //修改*T及其左孩子对的平衡因子
            {
                case LH:
                        T->bf = RH;
                        lc->bf = EH;
                        break;
                case EH:
                        T->bf = lc->bf = EH;
                        break;
                case RH:
                        T->bf = EH;
                        lc->bf = LH;
                        break;
            }
            rd->bf = EH;                //对*T的左子树作左旋平衡处理
            L_Rotate(T->lchild);    //对*T做右旋平衡处理
            R_Rotate(T);
    }
}

void RightBalance(BSTree &T)
{
    BSTree  rc, rd;  
    rc = T->rchild;  
    // 检查*T的右子树的平衡度,并作相应平衡处理  
    switch (rc->bf)  
    {  
        case RH:    // 新结点插入在*T的右孩子的右子树上,要作单左旋处理  
                T->bf = rc->bf = EH;  
                L_Rotate(T);  
                break;  
        case LH:    // 新结点插入在*T的右孩子的左子树上,要作双旋处理  
                rd = rc->lchild; // rd指向*T的右孩子的左子树根  
                switch (rd->bf)  
                {  
                // 修改*T及其右孩子的平衡因子  
                case RH:
                        T->bf=LH;  
                         rc->bf=EH;  
                         break;
                case EH:
                        T->bf=rc->bf=EH;   
                         break;  
                case LH:
                        T->bf=EH;  
                        rc->bf=RH;  
                }  
                rd->bf=EH;  
                R_Rotate(T->rchild);     // 对*T的右子树作右旋平衡处理  
                L_Rotate(T);            // 对*T作左旋平衡处理  
    }
}

int InsertAVL(BSTree &T, ElemType e, bool &taller)  
{  
    if(!T)  // 插入新结点,树“长高”,置taller为TRUE  
    {  
        T = (BSTree)malloc(sizeof(BSTNode));  
        T->data = e;  
        T->lchild = T->rchild = NULL;  
        T->bf = EH;  
        taller = TRUE;  
    }  
    else      
    {  
        // 树中已存在和e有相同关键字的结点则不再插入  
        if EQ(e.key, T->data.key)  
        {  
            taller = FALSE;  
            return FALSE;  
        }  
        // 应继续在*T的左子树中进行搜索  
        if LT(e.key, T->data.key)  
        {  
            if (!InsertAVL(T->lchild, e, taller))    // 未插入  
                return FALSE;  
            if (taller) //  已插入到*T的左子树中且左子树“长高”  
            {  
                switch (T->bf)   // 检查*T的平衡度  
                {  
                case LH: // 原本左子树比右子树高,需要作左平衡处理  
                    LeftBalance(T);  
                    taller=FALSE;  
                    break;  
                case EH: // 原本左、右子树等高,现因左子树增高而使树增高  
                    T->bf=LH;  
                    taller=TRUE;  
                    break;  
                case RH: T->bf=EH; // 原本右子树比左子树高,现左、右子树等高  
                    taller=FALSE;  
                }  
            }  
        }  
        // 应继续在*T的右子树中进行搜索  
        else  
        {  
            if (!InsertAVL(T->rchild, e, taller))    // 未插入  
                return FALSE;  
            if (taller) // 已插入到T的右子树且右子树“长高”  
            {  
                switch (T->bf)  
                {  
                case LH:    // 原本左子树比右子树高,现左、右子树等高  
                    T->bf = EH;  
                    taller = FALSE;  
                    break;  
                case EH:    // 原本左、右子树等高,现因右子树增高而使树增高  
                    T->bf = RH;  
                    taller = TRUE;  
                    break;  
                case RH:    // 原本右子树比左子树高,需要作右平衡处理  
                    RightBalance(T);  
                    taller = FALSE;  
                }  
            }  
        }  
    }  
    return TRUE;  
}  

void Visit(ElemType e)
{
    cout<<e.key<<" ";
}

void InOrderTraverse(BSTree T, void(*Visit)(ElemType))  //中序遍历
{
    if(T)
    {
        InOrderTraverse(T->lchild,Visit);
        Visit(T->data);
        InOrderTraverse(T->rchild,Visit);
    }
}

int _tmain(int argc, _TCHAR* argv[])
{
    ElemType R[6] = {{13,'A'},{24,'B'},{37,'C'},{90,'D'},{53,'E'},{80,'F'}};
    BSTree T = NULL;
    bool taller = FALSE;
    for(int i=0; i<6; i++)
        InsertAVL(T,R[i],taller);
     InOrderTraverse (T,Visit);
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值