C++實現平衡二叉樹的操作

平衡二叉樹傳統的旋轉方法不易理解,通過分析二叉排序樹的基本原理,[張標漢. 平衡二叉樹調整教學探討[J]. 計算機教育, 2009(10):53-54.]提出一種易於理解的平衡二叉樹調整方法。

以下是基於此方法的C++實現。

 

//平衡二叉樹
/*
1.輸入一個數列L,生成一棵平衡二叉樹T
2.對平衡二叉樹T作遞增、遞減輸出
3. 計算平衡二叉樹T的平均查找長度,輸出結果
//4.在二叉排序樹T上刪除指定結點
5.輸出平衡二叉樹T中指定結點的平衡因子
 */
#include <iostream>
#include <iostream>
#include <conio.H>
#include <stdlib.h>
#include <ctime>
#include <cmath>
using namespace std;

#define N 100
struct BiNode
{
    int data;
    BiNode * lchild, * rchild;
};

class BiSortTree
{
public:
    BiSortTree(int r[],int n);
    BiSortTree();
    ~BiSortTree(){}
    void Creat(int r[],int n);
    void InsertBST(BiNode * &root,BiNode * &s);
    void DeleteBST(BiNode * p,BiNode * f);
    BiNode * SearchBST(BiNode * root,int k);
    BiNode * SearchBSTFarther(BiNode * root,BiNode *  son);
    void IncreasingTraverse(BiNode * root);
    void DecreasingTraverse(BiNode * root);
    BiNode * GetRoot();
    int GetLeafNumCount();
    int GetDeep(BiNode * root,int k);
    int height(BiNode * root);
    int GetBalanceFactor(BiNode * tNode);
    BiNode * FindMinSubTree(BiNode * &s);
    void  Adjust(BiNode *minroot,BiNode * &s);
private:
    BiNode * root;
    void AddLeafNum(int num);
    int LeafNum[N];
    int LeafNumCount;
};


BiNode * BiSortTree::GetRoot()
{
    return root;
}

int BiSortTree::height(BiNode * root)
{
    if(root==NULL) return 0;
    else
    {
        int hl=height(root->lchild);
        int hr=height(root->rchild);
        return hl>hr?hl+1:hr+1;
    }
}

//構造二叉排序樹
BiSortTree::BiSortTree(int r[],int n)
{
    Creat(r,n);
}

BiSortTree::BiSortTree()
{
    LeafNumCount=0;
}

void BiSortTree::Creat(int r[],int n)
{
    int i;
    root=NULL;
    LeafNumCount=0;
    for(i=0;i<n;i++)
    {
        BiNode * s=new BiNode;
        s->lchild=s->rchild=NULL;
        s->data=r[i];
        InsertBST(root,s);
        //cout<<"Creat Traverse"<<endl;
        //IncreasingTraverse(root);cout<<endl;
    }
}
BiNode * BiSortTree::FindMinSubTree(BiNode * &s){
    BiNode *t=root,*bnd[N];
    int i=0;
    while(t!=s){
        if(abs(GetBalanceFactor(t))>1)
            bnd[i++]=t;
        if(s->data<t->data)t=t->lchild;
        else t=t->rchild;
        }
    if(i>0)return bnd[i-1];else return NULL;
    }
void    BiSortTree::Adjust(BiNode *minroot,BiNode * &s){
    BiNode *A=minroot,*B,*C;
    if(s->data<A->data)B=A->lchild;
    else B=A->rchild;
    if(s->data<B->data)C=B->lchild;
    else C=B->rchild;
    BiNode *F=SearchBSTFarther(root,A);
    if(C->data<B->data&&B->data<A->data)//LL
    {
        cout<<"LL"<<endl;
        A->lchild=B->rchild;
        B->rchild=A;
        if(F!=NULL)if(F->lchild==A)F->lchild=B;
                   else F->rchild=B;
        else root=B;
        }
    if(A->data<B->data&&B->data<C->data)//RR
    {cout<<"RR"<<endl;
        A->rchild=B->lchild;
        B->lchild=A;
        if(F!=NULL)if(F->lchild==A)F->lchild=B;
                   else F->rchild=B;
        else root=B;
        }
    if(B->data<C->data&&C->data<A->data)//LR
    {cout<<"LR"<<endl;
        B->rchild=C->lchild;A->lchild=C->rchild;
        C->lchild=B;C->rchild=A;
        if(F!=NULL)if(F->lchild==A)F->lchild=C;
                   else F->rchild=C;
        else root=C;
        }
    if(B->data>C->data&&C->data>A->data)//RL
    {cout<<"RL"<<endl;
        A->rchild=C->lchild;B->lchild=C->rchild;
        C->lchild=A;C->rchild=B;
        if(F!=NULL)if(F->lchild==A)F->lchild=C;
                   else F->rchild=C;
        else root=C;
        }
    }
//插入
void BiSortTree::InsertBST(BiNode * &root,BiNode * &s)
{   BiNode *minroot;
//cout<<"InsertBST"<<s->data<<endl;
    if(root==NULL)
    {
        root=s;
        minroot=FindMinSubTree(s);
        if(minroot!=NULL){
            cout<<"FindMinSubTree"<<minroot->data<<endl;
            Adjust(minroot,s);
            }
    }
    else if(s->data<root->data)
    {
        InsertBST(root->lchild,s);
    }
    else
    {
        InsertBST(root->rchild,s);
    }
}
void BiSortTree::DeleteBST(BiNode * p,BiNode *f)
{
    if((p->lchild==NULL)&&(p->rchild==NULL)) // delete leaf node
    {
        if(f->lchild==p)    f->lchild=NULL;else f->rchild=NULL;
        delete p;
    }
    else if(p->rchild==NULL) //delete node only has lchild
    {
        if(f->lchild==p) f->lchild=p->lchild;else f->rchild=p->lchild;
        delete p;
    }
    else if(p->lchild==NULL) //delete node only has rchild
    {
        if(f->lchild==p) f->lchild=p->rchild;else f->rchild=p->rchild;
        delete p;
    }
    else //delete node has both rchild and lchild
    {
        BiNode * par=p;
        BiNode * s=p->rchild;
        while(s->lchild!=NULL)
            {
                par=s;
                s=s->lchild;
            }
        p->data=s->data;
        if(par==p)        par->rchild=s->rchild;
        else    par->lchild=s->rchild;
        delete s;

    }
}

//查找
BiNode * BiSortTree::SearchBST(BiNode * root,int k)
{
    if(root==NULL)
    {
        return NULL;
    }
    else if((root->data)==k)
    {
        return root;
    }
    else if((root->data)<k)
    {
        return SearchBST(root->rchild,k);
    }
    else
    {
        return SearchBST(root->lchild,k);
    }
}

int BiSortTree::GetDeep(BiNode * root,int k)
{
    if(root==NULL)
    {
        return 0;
    }
    else if((root->data)==k)
    {
        return 1;
    }
    else if((root->data)<k)
    {
        return GetDeep(root->rchild,k)+1;
    }
    else
    {
        return GetDeep(root->lchild,k)+1;
    }
}


BiNode * BiSortTree::SearchBSTFarther(BiNode * root,BiNode *  son)
{
    if(root==NULL)
    {
        return NULL;
    }
    else if((root->data)<son->data)
    {
        if( ( (root->lchild)==son) || ( (root->rchild)==son) )
        {
            return root;
        }
        else
        {
            return SearchBSTFarther(root->rchild,son);
        }
    }
    else
    {
        if( ( (root->lchild)==son) || ( (root->rchild)==son) )
        {
            return root;
        }
        else
        {
            return SearchBSTFarther(root->lchild,son);
        }
    }
}

//遍歷
void BiSortTree::IncreasingTraverse(BiNode * root)
{
    if(root==NULL)
    {
        return ;
    }
    IncreasingTraverse(root->lchild);
    cout<<root->data<<" ";
    IncreasingTraverse(root->rchild);
}

void BiSortTree::DecreasingTraverse(BiNode * root)
{
    if(root==NULL)
    {
        return ;
    }
    DecreasingTraverse(root->rchild);
    cout<<root->data<<" ";
    DecreasingTraverse(root->lchild);
}

int BiSortTree::GetBalanceFactor(BiNode * tNode)
{
    return height(tNode->lchild)-height(tNode->rchild);
}

int main()
{
    //cout<<"ok"<<endl;
    int L[N]={1,2,8,7,6,5,3,4};
    BiSortTree T;
    int i,n=8,x;
    int SumDeep=0;
//    cout<<"Input the numbers(End by -1):"<<endl;
/*    cin>>n;
    for(i=0;i<n;i++)
        cin>>L[i];*/
    cout<<"數列L中有"<<n<<"個整數:\n";
    for(i=0;i<n;i++)
        cout<<L[i]<<"  ";
    cout<<endl;
    T.Creat(L,n);

    cout<<"對二叉排序樹T作遞增輸出:"<<endl;
    T.IncreasingTraverse(T.GetRoot());
    cout<<endl;
    cout<<"對二叉排序樹T作遞減輸出:"<<endl;
    T.DecreasingTraverse(T.GetRoot());
    cout<<endl;

    for(i=0;i<n;i++)
        {
            SumDeep+=T.GetDeep(T.GetRoot(),L[i]);
        }
    cout<<"二叉排序樹T的平均查找長度: "<<(SumDeep*1.0/n)<<endl;

    /*cin>>x;
    cout<<"在二叉排序樹T上刪除值爲"<<x<<"的結點。\n";
    BiNode * DelNode=T.SearchBST(T.GetRoot(),x);
    if(DelNode!=NULL)
            {
                BiNode * DelNodeFarther=T.SearchBSTFarther(T.GetRoot(),DelNode);
                T.DeleteBST(DelNode,DelNodeFarther);
            }
    else        cout<<"值爲"<<x<<"的結點不存在。"<<endl;
    cout<<"對二叉排序樹T作遞增輸出:"<<endl;
    T.IncreasingTraverse(T.GetRoot());
    cout<<endl;
    cout<<"對二叉排序樹T作遞減輸出:"<<endl;
    T.DecreasingTraverse(T.GetRoot());
    cout<<endl;
*/
    for(i=0;i<n;i++){
        BiNode * tNode=T.SearchBST(T.GetRoot(),L[i]);
        if(tNode!=NULL)cout<<"值爲"<<L[i]<<"的結點的平衡因子="<<T.GetBalanceFactor(tNode)<<endl;
        else cout<<"值爲"<<L[i]<<"的結點不存在。"<<endl;
    }

    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章