1. 程式人生 > >平衡二叉樹(C++實現)

平衡二叉樹(C++實現)

  • 平衡二叉樹的建立(插入節點)

  • 二叉樹的刪除節點

 刪除節點演算法思想:首先第一步需要找到要刪除的節點x,並分情況進行處理:

  1. 如果要刪除的節點為葉子節點,就找到了要刪除的節點,假設節點p是一個葉子節點,則直接刪除它。如果刪除節點之後,二叉樹不平衡,則需要進行相關的調整。
  2. 如果要刪除的節點為只有一棵子樹的節點,就找到了要刪除的節點,假設p是一個只有一棵子樹的節點,則將p刪除,p節點的子樹的根將成為p父節點f的子節點。如果刪除節點之後,二叉樹不平衡,則需要進行相關的調整。
  3. 如果要刪除的節點既有左子樹,又有右子樹,則如果該節點的平衡因子為0或者1,則找到其左子樹中具有最大值的節點max(我們只討論有序平衡二叉樹,並且有序平衡二叉樹中任意一個節點的左子樹上的所有節點的值小於該節點的值,右子樹上所有節點的值大於該節點的值),將max的內容與x的內容交換(只替換儲存的真正的資料,不替換指標,平衡因子等用於管理目的的資訊),並且max即為新的要刪除的節點。由於樹是有序的,因而這樣找到的節點要麼是一個葉子節點,要麼是一個沒有右子樹的節點。如果該節點的平衡因子為-1,則找到其右節點中具有最小值的節點min,將min的內容與x的內容交換,並且min即為新的要刪除的節點。由於樹是有序的,因而這樣找到的節點要麼是一個葉子節點,要麼是一個沒有左子樹的節點。在找到要刪除的節點後下一步就是刪除節點,假設要刪除的節點為p,其父節點為f,顯然此時p要麼是一個葉子節點,要麼是一個只有一棵子樹的節點:如果delete是一個葉子節點,則直接刪除它。如果delete是一個只有一棵子樹的節點,則將delete刪除,delete節點的子樹的根將成為parent的子節點。如果刪除節點之後,二叉樹不平衡,則需要進行相關的調整。
  • 二叉樹節點的查詢

  1. 若待查詢節點的數值小於根節點數值,則查詢根節點的左子樹
  2. 若待查詢節點的數值大於根節點數值,則查詢根節點的右子樹
  3. 若根節點為葉子節點且不等於待查詢節點,則查詢失敗。
  4. 若根節點的數值等於葉子節點的數值,則查詢成功。
  • 演算法實現:

#ifndef _BALANCEBITREE_H_
#define _BALANCEBITREE_H_
#include <iostream>
#include <cmath>

using namespace std;

template< class ElementType>
struct Node{
    ElementType data;
    struct Node *lChild;
    struct Node *rChild;
    int balanceFctor;           //平衡因子
};
template< class ElementType>
class BalanceBiTree{
public :
    BalanceBiTree(Node<ElementType> *& T);                       //初始化
    static void menu();                                          //選單
    void destory(Node<ElementType> *& T);                        //銷燬二叉樹
    void insert(Node<ElementType> *& T,Node<ElementType> * S);   //將指標S所指節點插入二叉排序中
    int BiTreeDepth(Node <ElementType> * T);                     //求樹的高度
    int getNodeFactor(Node<ElementType> *T);                     //求樹中節點的平衡因子
    void factorForTree(Node<ElementType> *&T);                   //求樹中的每個節點的平衡因子
    void nodeFctorIsTwo(Node<ElementType> *&T,Node<ElementType> *&p);        //獲得平衡因子為2或-2的節點
    void nodeFctorIsTwoFather(Node<ElementType> *&T,Node<ElementType> *&f);  //獲得平衡因子為2或-2的節點的父節點
    void LLAdjust(Node<ElementType> *&T,Node<ElementType> *&p,Node<ElementType> *&f);                        //LL調整
    void LRAdjust(Node<ElementType> *&T,Node<ElementType> *&p,Node<ElementType> *&f);                        //LR調整
    void RLAdjust(Node<ElementType> *&T,Node<ElementType> *&p,Node<ElementType> *&f);                        //RL調整
    void RRAdjust(Node<ElementType> *&T,Node<ElementType> *&p,Node<ElementType> *&f);                        //RR調整
    void AllAdjust(Node<ElementType> *&T);                       //整合四種調整,並實時更新平衡因子
    void preOrderTraverse(Node<ElementType> *T,int level);       //先序遍歷輸出
    void inOrderTraverse(Node <ElementType> *T,int level);       //中序遍歷輸出
    void BiTreeToArray(Node <ElementType> *T,ElementType A[],int i,int &count); //二叉樹轉陣列
    void LevelTraverse(Node <ElementType> *T,ElementType B[],int num);          //對二叉連結串列表示的二叉樹,按從上到下,從左到右列印結點值,即按層次列印
    void createSubBalanceBiTree(Node<ElementType> *&T);          //互動建立二叉平衡樹
    void createBalanceBiTreeFromArray(Node<ElementType> *&T,ElementType A[],int n);//從陣列中建立平衡二叉樹
    void search(Node <ElementType> *&T,Node <ElementType> *&p,ElementType x);          //查詢元素x
    Node <ElementType> * getElementFatherPointer(Node <ElementType> *&T,Node <ElementType> *&f,ElementType x); //獲取某個元素的父親指標,不存在返回NULL
    void getPriorElement(Node <ElementType> *&T,ElementType &min,ElementType &max);                 //獲取前驅元素
    Node <ElementType> * getElementPriorPointer(Node <ElementType> *&T);  //獲取某個元素的前驅指標
    void getNextElement(Node <ElementType> *&T,ElementType &min,ElementType &max);                  //獲取後繼元素
    Node <ElementType> * getElementNextPointer(Node <ElementType> *&T);   //獲取某個元素的後繼指標
    void deleteLeafNode(Node <ElementType> *&T,Node <ElementType> *&p,Node <ElementType> *&f);        //刪除葉子節點
    void deleteOneBranchNode(Node <ElementType> *&T,Node <ElementType> *&p,Node <ElementType> *&f);   //刪除僅有左子樹或只有右子樹的節點
    void deleteTwoBranchNode(Node <ElementType> *&T,Node <ElementType> *&p);   //刪除既有左子樹又有右子樹的節點
    void deleteOperate(Node <ElementType> *&T,ElementType x);         //整合刪除的三種情況的操作
private :
    Node<ElementType> *root;   //樹根
};
//初始化
template< class ElementType>
BalanceBiTree<ElementType>::BalanceBiTree(Node<ElementType> *& T)
{
    T=NULL;
}
//選單
template< class ElementType>
void BalanceBiTree<ElementType>::menu()
{
    cout<<"*************************************************"<<endl;
    cout<<"0退出並銷燬平衡二叉樹"<<endl;
    cout<<"1二分查詢演算法實現查詢元素"<<endl;
    cout<<"2插入結點構建二叉排序樹(二叉平衡樹)"<<endl;
    cout<<"3二叉排序樹中查詢指定值的結點"<<endl;
    cout<<"4二叉排序樹中刪除特定值的結點"<<endl;
    cout<<"5陣列A[1..26]遞增有序,設計演算法以構造一棵平衡的二叉排序樹"<<endl;
    cout<<"6樹形輸出"<<endl;
    cout<<"*************************************************"<<endl;
}
//銷燬二叉樹
template< class ElementType>
void BalanceBiTree<ElementType>::destory(Node<ElementType> *& T)
{
    if(T)
    {
        destory(T->lChild);
        destory(T->rChild);
        delete T;
    }
}
//將指標S所指節點插入二叉排序中
template< class ElementType>
void BalanceBiTree<ElementType>::insert(Node<ElementType> *& T,Node<ElementType> * S)
{
    if(T==NULL)
        T=S;
    else if(S->data<T->data)
        insert(T->lChild,S);
    else
        insert(T->rChild,S);
}
//求樹的高度
template< class ElementType>
int BalanceBiTree<ElementType>::BiTreeDepth(Node <ElementType> * T)
{
    int m,n;
    if(T==NULL)
        return 0;           //空樹,高度為0
    else{
        m=BiTreeDepth(T->lChild);   //求左子樹高度(遞迴)
        n=BiTreeDepth(T->rChild);   //求右子樹高度(遞迴)
        if(m>n)
        {
            return m+1;
        }
        else{
            return n+1;
        }
    }
}
//求樹中節點的平衡因子
template< class ElementType>
int BalanceBiTree<ElementType>::getNodeFactor(Node<ElementType> *T)
{
    int m=0,n=0;
    if(T)
    {
        m=BiTreeDepth(T->lChild);
        n=BiTreeDepth(T->rChild);
    }
    return m-n;
}
//求樹中的每個節點的平衡因子
template< class ElementType>
void BalanceBiTree<ElementType>::factorForTree(Node<ElementType> *&T)
{
    if(T)
    {
        T->balanceFctor=getNodeFactor(T);
        factorForTree(T->lChild);
        factorForTree(T->rChild);
    }
}
//獲得平衡因子為2或-2的節點
template< class ElementType>
void BalanceBiTree<ElementType>::nodeFctorIsTwo(Node<ElementType> *&T,Node<ElementType> *&p)
{
    if(T)
    {
        if(T->balanceFctor==2||T->balanceFctor==-2)
        {
             p=T;
        }
       nodeFctorIsTwo(T->lChild,p);
       nodeFctorIsTwo(T->rChild,p);
    }
}
//獲得平衡因子為2或-2的節點的父節點
template< class ElementType>
void BalanceBiTree<ElementType>::nodeFctorIsTwoFather(Node<ElementType> *&T,Node<ElementType> *&f)
{
    if(T)
    {
        if(T->lChild!=NULL)
        {
            if(T->lChild->balanceFctor==2||T->lChild->balanceFctor==-2)
            {
                f=T;
            }
        }
        if(T->rChild!=NULL)
        {
            if(T->rChild->balanceFctor==2||T->rChild->balanceFctor==-2)
            {
                f=T;
            }
        }
        nodeFctorIsTwoFather(T->lChild,f);
        nodeFctorIsTwoFather(T->rChild,f);
    }
}
//LL調整
template< class ElementType>
void BalanceBiTree<ElementType>::LLAdjust(Node<ElementType> *&T,Node<ElementType> *&p,Node<ElementType> *&f)
{
    Node<ElementType> *r;
    if(T==p)           //->balanceFctor==2&&T->lChild->balanceFctor!=2
    {
        cout<<"LL調整"<<endl;
        T=p->lChild;        //將P的左孩子提升為新的根節點
        r=T->rChild;
        T->rChild=p;        //將p降為其左孩子的右孩子
        p->lChild=r;        //將p原來的左孩子的右孩子連線其p的左孩子

    }
    else{
        if(f->lChild==p)     //f的左孩子是p
        {
            cout<<"LL調整"<<endl;
            f->lChild=p->lChild;        //將P的左孩子提升為新的根節點
            r=f->lChild->rChild;
            f->lChild->rChild=p;        //將p降為其左孩子的右孩子
            p->lChild=r;        //將p原來的左孩子的右孩子連線其p的左孩子
        }
        if(f->rChild==p)     //f的左孩子是p
        {
            cout<<"LL調整"<<endl;
            f->rChild=p->lChild;        //將P的左孩子提升為新的根節點
            r=f->rChild->rChild;
            f->rChild->rChild=p;        //將p降為其左孩子的右孩子
            p->lChild=r;        //將p原來的左孩子的右孩子連線其p的左孩子
        }
    }
}
//LR調整
template< class ElementType>
void BalanceBiTree<ElementType>::LRAdjust(Node<ElementType> *&T,Node<ElementType> *&p,Node<ElementType> *&f)
{
    Node<ElementType> *l,*r;
    if(T==p)           //->balanceFctor==2&&T->lChild->balanceFctor!=2
    {
        cout<<"LR調整"<<endl;
        T=p->lChild->rChild;    //將P的左孩子的右孩子提升為新的根節點
        r=T->rChild;
        l=T->lChild;
        T->rChild=p;
        T->lChild=p->lChild;
        T->lChild->rChild=l;
        T->rChild->lChild=r;
    }
    else{
        if(f->rChild==p)     //f的左孩子是p
        {
            cout<<"LR調整"<<endl;
            f->rChild=p->lChild->rChild;    //將P的左孩子的右孩子提升為新的根節點
            r=f->rChild->rChild;
            l=f->rChild->lChild;
            f->rChild->rChild=p;
            f->rChild->lChild=p->lChild;
            f->rChild->lChild->rChild=l;
            f->rChild->rChild->lChild=r;
        }
        if(f->lChild==p)     //f的左孩子是p
        {
            cout<<"LR調整"<<endl;
            f->lChild=p->lChild->rChild;    //將P的左孩子的右孩子提升為新的根節點
            r=f->lChild->rChild;
            l=f->lChild->lChild;
            f->lChild->rChild=p;
            f->lChild->lChild=p->lChild;
            f->lChild->lChild->rChild=l;
            f->lChild->rChild->lChild=r;
        }
    }
}
//RL調整
template< class ElementType>
void BalanceBiTree<ElementType>::RLAdjust(Node<ElementType> *&T,Node<ElementType> *&p,Node<ElementType> *&f)
{
    Node<ElementType> *l,*r;
    if(T==p)           //->balanceFctor==-2&&T->rChild->balanceFctor!=-2
    {
            cout<<"RL調整"<<endl;
            T=p->rChild->lChild;
            r=T->rChild;
            l=T->lChild;
            T->lChild=p;
            T->rChild=p->rChild;
            T->lChild->rChild=l;
            T->rChild->lChild=r;
    }
    else{
            if(f->rChild==p)     //f的左孩子是p
            {
                cout<<"RL調整"<<endl;
                f->rChild=p->rChild->lChild;
                r=f->rChild->rChild;
                l=f->rChild->lChild;
                f->rChild->lChild=p;
                f->rChild->rChild=p->rChild;
                f->rChild->lChild->rChild=l;
                f->rChild->rChild->lChild=r;
            }
            if(f->lChild==p)     //f的左孩子是p
            {
                cout<<"RL調整"<<endl;
                f->lChild=p->rChild->lChild;
                r=f->lChild->rChild;
                l=f->lChild->lChild;
                f->lChild->lChild=p;
                f->lChild->rChild=p->rChild;
                f->lChild->lChild->rChild=l;
                f->lChild->rChild->lChild=r;
            }
    }
}
//RR調整
template< class ElementType>
void BalanceBiTree<ElementType>::RRAdjust(Node<ElementType> *&T,Node<ElementType> *&p,Node<ElementType> *&f)
{
    Node<ElementType> *l;
    if(T==p)                   //->balanceFctor==-2&&T->rChild->balanceFctor!=-2
    {
            cout<<"RR調整"<<endl;
            T=p->rChild;        //將P的右孩子提升為新的根節點
            l=T->lChild;
            T->lChild=p;        //將p降為其右孩子的左孩子
            p->rChild=l;        //將p原來的右孩子的左孩子連線其p的右孩子
        //注意:p->rChild->balanceFctor==0插入節點時用不上,刪除節點時可用
    }
    else{
            if(f->rChild==p)     //f的右孩子是p
            {
                cout<<"RR調整"<<endl;
                f->rChild=p->rChild;        //將P的右孩子提升為新的根節點
                l=f->rChild->lChild;
                f->rChild->lChild=p;        //將p降為其右孩子的左孩子
                p->rChild=l;        //將p原來的右孩子的左孩子連線其p的右孩子
            }
            if(f->lChild==p)     //f的左孩子是p
            {
                cout<<"RR調整"<<endl;
                f->lChild=p->rChild;        //將P的左孩子提升為新的根節點
                l=f->lChild->lChild;
                f->lChild->lChild=p;        //將p降為其左孩子的左孩子
                p->rChild=l;        //將p原來的右孩子的左孩子連線其p的右孩子
            }
    }
}
//整合四種調整,並實時更新平衡因子
template< class ElementType>
void BalanceBiTree<ElementType>::AllAdjust(Node<ElementType> *&T)
{
    Node<ElementType> *f=NULL,*p=NULL;
    factorForTree(T);
    nodeFctorIsTwoFather(T,f);
    nodeFctorIsTwo(T,p);
    while(p)
    {
        factorForTree(T);
        if(p->balanceFctor==2&&(p->lChild->balanceFctor==1||p->lChild->balanceFctor==0))
        {
            LLAdjust(T,p,f);
            factorForTree(T);
        }
        else if(p->balanceFctor==2&&p->lChild->balanceFctor==-1)
        {
            LRAdjust(T,p,f);
            factorForTree(T);
        }
        else if(p->balanceFctor==-2&&p->rChild->balanceFctor==1)
        {
            RLAdjust(T,p,f);
            factorForTree(T);
        }
        else if(p->balanceFctor==-2&&(p->rChild->balanceFctor==-1||p->rChild->balanceFctor==0))  //||p->rChild->balanceFctor==0
        {
            RRAdjust(T,p,f);
        }
        f=NULL;
        p=NULL;
        nodeFctorIsTwoFather(T,f);
        nodeFctorIsTwo(T,p);
    }
}
//先序遍歷輸出
template< class ElementType>
void BalanceBiTree<ElementType>::preOrderTraverse(Node<ElementType> *T,int level)
{
    if(T)
    {
        cout<<"先序"<<"("<<T->data<<","<<level<<")"<<" ";
        preOrderTraverse(T->lChild,level+1);
        preOrderTraverse(T->rChild,level+1);
    }
}
//中序遍歷演算法
template<class ElementType>
void BalanceBiTree<ElementType>::inOrderTraverse(Node <ElementType> * T,int level)
{
    if(T)
    {
        inOrderTraverse(T->lChild,level+1);  //遞迴呼叫先序遍歷左子樹
        cout<<"中序"<<"("<<T->data<<","<<level<<")"<<" ";           //訪問根節點
        inOrderTraverse(T->rChild,level+1);  //遞迴呼叫先序遍歷右子樹
    }
}
//二叉樹轉陣列
template<class ElementType>
void BalanceBiTree<ElementType>::BiTreeToArray(Node <ElementType> *T,ElementType A[],int i,int &count)
{
    if(T!=NULL)
    {
        A[i]=T->data;
        if(i>count)
            count=i;
        BiTreeToArray(T->lChild,A,2*i,count);
        BiTreeToArray(T->rChild,A,2*i+1,count);
    }
}
//對二叉連結串列表示的二叉樹,按從上到下,從左到右列印結點值,即按層次列印
template<class ElementType>
void BalanceBiTree<ElementType>::LevelTraverse(Node <ElementType> *T,ElementType B[],int num)
{
    int n,i,j,t,q,s,p,m=0,k=0;
    n=(int)((log(num)/log(2))+1);
    p=n;
    for(i=0;i<n;i++)
    {
        k=pow(2,m)+k;
        t=pow(2,m);
        j=pow(2,p-1)-1;
        q=pow(2,p)-1;
        s=q;
        for(j;j>0;j--)
        {
            cout<<" ";
        }
        for(t;t<=k;t++)
        {
            if(B[t]==0)
            {
                cout<<"*";
                for(q;q>0;q--)
                cout<<" ";
                q=s;
            }
            else{
                cout<<B[t];
                for(q;q>0;q--)
                cout<<" ";
                q=s;
            }
        }
        m++;
        p--;
        j=n-i-1;
        cout<<endl;
    }
}
//互動建立二叉平衡樹
template< class ElementType>
void BalanceBiTree<ElementType>::createSubBalanceBiTree(Node<ElementType> *&T)
{
    int level=1;
    int i=1,j=0;
    int A[100]={0};
    int length=0;
    ElementType x;
    Node<ElementType> * S,*p;
    T=new Node<ElementType>;
    T->balanceFctor=0;
    T->lChild=NULL;
    T->rChild=NULL;
    p=T;
    cout<<"請輸入元素(-9999退出):";
    cin>>x;
    T->data=x;
    while(x!=-9999)
    {
        cout<<"請輸入元素:";
        cin>>x;
        if(x==-9999)
            return;
        S=new Node<ElementType>;
        S->data=x;
        S->balanceFctor=0;
        S->lChild=NULL;
        S->rChild=NULL;
        insert(p,S);
        AllAdjust(T);
        p=T;
        inOrderTraverse(T,level);
        cout<<endl;
        BiTreeToArray(T,A,i,length);
        cout<<"其樹狀圖為:"<<endl;
        LevelTraverse(T,A,length);
        j=0;
        for(j;j<100;j++)
        A[j]=0;
        level=1;
        i=1;
    }
}
//從陣列中建立平衡二叉樹
template< class ElementType>
void BalanceBiTree<ElementType>::createBalanceBiTreeFromArray(Node<ElementType> *&T,ElementType A[],int n)
{
    Node<ElementType> * S,*p;
    int i=1;
    T=new Node<ElementType>;
    T->balanceFctor=0;
    T->lChild=NULL;
    T->rChild=NULL;
    p=T;
    T->data=A[0];
    n=n-1;
    while(n)
    {
        S=new Node<ElementType>;
        S->data=A[i];
        S->balanceFctor=0;
        S->lChild=NULL;
        S->rChild=NULL;
        insert(p,S);
        AllAdjust(T);
        p=T;
        i++;
        n--;
    }
}
//查詢元素x
template<class ElementType>
void BalanceBiTree<ElementType>::search(Node <ElementType> *&T,Node <ElementType> *&p,ElementType x)
{
   if(T)
   {
       if(T->data==x)
        p=T;
       search(T->lChild,p,x);
       search(T->rChild,p,x);
   }
}
 //獲取某個元素的父親指標,不存在返回NULL
template<class ElementType>
Node <ElementType> * BalanceBiTree<ElementType>::getElementFatherPointer(Node <ElementType> *&T,Node <ElementType> *&f,ElementType x)
{
    if(T)
    {
        if(T->lChild!=NULL)
        {
            if(T->lChild->data==x)
                f=T;
        }
        if(T->rChild!=NULL)
        {
            if(T->rChild->data==x)
                f=T;
        }
        getElementFatherPointer(T->lChild,f,x);
        getElementFatherPointer(T->rChild,f,x);
    }
}
//獲取前驅元素
template<class ElementType>
void BalanceBiTree<ElementType>::getPriorElement(Node <ElementType> *&T,ElementType &min,ElementType &max)
{
    if(T)
    {
        min=T->data;
        if(min>max)
            max=min;
        getPriorElement(T->lChild,min,max);
        getPriorElement(T->rChild,min,max);
    }
}
//獲取某個元素的前驅指標
template<class ElementType>
Node <ElementType> * BalanceBiTree<ElementType>::getElementPriorPointer(Node <ElementType> *&T)
{
    Node <ElementType> *p;
    ElementType min=0,max=-9999;
    getPriorElement(T,min,max);
    search(T,p,max);
    return p;
}
//獲取後繼元素
 template<class ElementType>
void BalanceBiTree<ElementType>::getNextElement(Node <ElementType> *&T,ElementType &min,ElementType &max)
{
    if(T)
    {
        max=T->data;
        if(min>max)
            min=max;
        getNextElement(T->lChild,min,max);
        getNextElement(T->rChild,min,max);
    }
}
//獲取某個元素的後繼指標
template<class ElementType>
Node <ElementType> * BalanceBiTree<ElementType>::getElementNextPointer(Node <ElementType> *&T)
{
    Node <ElementType> *p;
    ElementType min=9999,max=0;
    getNextElement(T,min,max);
    search(T,p,min);
    return p;
}
//刪除葉子節點操作
template<class ElementType>
void BalanceBiTree<ElementType>::deleteLeafNode(Node <ElementType> *&T,Node <ElementType> *&p,Node <ElementType> *&f)
{
    if(p==NULL)
    {
        cout<<"此節點不存在,不能刪除"<<endl;
        return;
    }
    if(T==p)        //根節點即為葉子節點
    {
        delete p;
        T=NULL;
    }
    else{           //刪除節點為非根節點的葉子節點
        if(f->lChild==p)
        {
            delete p;
            f->lChild=NULL;
        }
        if(f->rChild==p)
        {
            delete p;
            f->rChild=NULL;
        }
    }
}
//刪除僅有左子樹或只有右子樹的節點
template<class ElementType>
void BalanceBiTree<ElementType>::deleteOneBranchNode(Node <ElementType> *&T,Node <ElementType> *&p,Node <ElementType> *&f)
{
    if(p==NULL)
    {
        cout<<"此節點不存在,不能刪除"<<endl;
        return;
    }
    if(T==p)
    {
        if(T->lChild==NULL&&T->rChild!=NULL)
        {
            T=p->rChild;
            delete p;
        }
        if(T->rChild==NULL&&T->lChild!=NULL)
        {
            T=p->lChild;
            delete p;
        }
    }
    else{
        if(p->lChild!=NULL)
        {
            if(f->lChild==p)
                f->lChild=p->lChild;
            else
                f->rChild=p->lChild;
        }
        if(p->rChild!=NULL)
        {
            if(f->lChild==p)
                f->lChild=p->rChild;
            else
                f->rChild=p->rChild;
        }
    }
}
//刪除既有左子樹又有右子樹的節點
template<class ElementType>
void BalanceBiTree<ElementType>::deleteTwoBranchNode(Node <ElementType> *&T,Node <ElementType> *&p)
{
    Node <ElementType> *f,*next,*prior;
    if(p==NULL)
    {
        cout<<"此節點不存在,不能刪除"<<endl;
        return;
    }
    if(p->balanceFctor==1)                             //p的平衡因子為1時,用p的前驅節點代替p
    {
        prior=getElementPriorPointer(p->lChild);             //獲得x的前驅指標
        if(prior->lChild!=NULL&&prior->rChild==NULL)   //情況一前驅節點只有左孩子
        {
           p->data=prior->data;
           prior->data=prior->lChild->data;
           delete prior->lChild;
           prior->lChild=NULL;
        }
        if(prior->lChild==NULL&&prior->rChild==NULL)    //情況二前驅節點為葉子節點
        {
            getElementFatherPointer(T,f,prior->data); //得到前驅節點的父節點
            p->data=prior->data;
            delete prior;
            f->rChild=NULL;
        }
    }
   else if(p->balanceFctor==-1)                             //p的平衡因子為-1時,用p的後繼節點代替p
    {
        next=getElementNextPointer(p->rChild);                //獲得x的後繼指標
        cout<<next->data;
        int level=1;
        if(next->rChild!=NULL&&next->lChild==NULL)      //情況一後繼節點只有右孩子
        {
           p->data=next->data;
           next->data=next->rChild->data;
           delete next->rChild;
           next->rChild=NULL;
        }
        else if(next->rChild==NULL&&next->lChild==NULL)       //情況二後繼節點為葉子節點
        {
            getElementFatherPointer(T,f,next->data);     //得到後繼節點的父節點
            p->data=next->data;
            delete next;
            f->lChild=NULL;
        }
    }
    else if(p->balanceFctor==0)     //p的平衡因子為0時,用p的前驅或後繼節點代替p,這裡用前驅
    {
        prior=getElementPriorPointer(p->lChild);               //獲得x的前驅指標
        if(prior->lChild!=NULL&&prior->rChild==NULL)     //情況一前驅節點只有左孩子
        {
           p->data=prior->data;
           prior->data=prior->lChild->data;
           delete prior->lChild;
           prior->lChild=NULL;
        }
        if(prior->lChild==NULL&&prior->rChild==NULL)      //情況二前驅節點為葉子節點
        {
            getElementFatherPointer(T,f,prior->data);     //得到前驅節點的父節點
            p->data=prior->data;
            delete prior;
            if(p==f)                                      //這塊需要特殊記憶,唯獨p->balanceFctor==0需要考慮***
                f->lChild=NULL;
            else
                f->rChild=NULL;

        }
    }
}
//整合刪除的三種情況的操作
template<class ElementType>
void BalanceBiTree<ElementType>::deleteOperate(Node <ElementType> *&T,ElementType x)
{
    Node <ElementType> *f,*p=NULL;
    search(T,p,x);
    getElementFatherPointer(T,f,x);
    if(p==NULL)
    {
        cout<<"不存在此節點,刪除失敗!"<<endl;
        return;
    }
    if(p->lChild==NULL&&p->rChild==NULL)  //情況一刪除節點為葉子節點
    {
        deleteLeafNode(T,p,f);
        if(T!=NULL)
           AllAdjust(T);
    }
    else if((p->lChild==NULL&&p->rChild!=NULL)||(p->lChild!=NULL&&p->rChild==NULL))
    {
        deleteOneBranchNode(T,p,f);
        if(T!=NULL)
           AllAdjust(T);
    }
    else                           //if(p->lChild!=NULL&&p->rChild!=NULL)
    {
        deleteTwoBranchNode(T,p);
        if(T!=NULL)
           AllAdjust(T);
    }
}
#endif // _BALANCEBITREE_H_
#include <iostream>
#include <Cstdlib>
#include "BalanceBiTree.h"

using namespace std;

//陣列、順序表的二分查詢
template<class ElementType>
int BinarySearch(ElementType A[],int n,ElementType x)
{
    int mid,low=0,high=n-1;
    while(low<=high)
    {
        mid=(low+high)/2;
        if(x==A[mid])
        {
            return mid;
        }
        else if(x<A[mid])
        {
            high=mid-1;
        }
        else{
            low=mid+1;
        }
    }
    return -1;
}
//初始化陣列
void initArray(int A[])
{
    int i=0;
    for(i;i<100;i++)
        A[i]=0;
}
int main()
{
    int x,y;
    int i=1;
    int level=1;
    int A[100]={0};
    int B[100]={0};
    int length=0;       //儲存陣列A的有效元素個數
    Node<int> * root;
    Node<int> * p;
    BalanceBiTree<int> T(root);
    BalanceBiTree<int>::menu();
    cout<<"請輸入執行序號:";
    cin>>x;
    while(x!=0)
    {
        switch(x)
        {
            case 1:
                if(root!=NULL)
                    T.destory(root);
                length=0;
                cout<<"請輸入陣列元素的值:";
                cin>>y;
                while(y!=-9999)
                {
                    A[length]=y;
                    length++;
                    cout<<"請輸入陣列元素的值:";
                    cin>>y;
                }
                cout<<"請輸入要查詢元素的值:";
                cin>>x;
                if(BinarySearch(A,length+1,x)==-1)
                    cout<<"不存i=1;在!"<<endl;
                else{
                    cout<<"存在,其下標為:"<<BinarySearch(A,length+1,x)<<endl;
                }
            break;
            case 2:
                T.createSubBalanceBiTree(root);
            break;
            case 3:
                cout<<"請輸入要查詢元素的值:";
                cin>>x;
                T. search(root,p,x);
                if(p!=NULL)
                {
                    if(p->data==x)
                        cout<<"元素存在!"<<endl;
                    else
                        cout<<"元素不存在!"<<endl;
                }
                else{
                    cout<<"元素不存在!"<<endl;
                }
            break;
            case 4:
                i=1;
                initArray(A);
                level=1;
                cout<<"請輸入要刪除元素的值:";
                cin>>x;
                T.deleteOperate(root,x);
                T.inOrderTraverse(root,level);
                T.BiTreeToArray(root,A,i,length);
                cout<<"其樹狀圖為:"<<endl;
                T.LevelTraverse(root,A,length);
            break;
            case 5:
                initArray(A);
                if(root!=NULL)
                    T.destory(root);
                length=0;
                y=1;
                for(y;y<=26;y++)
                {
                    A[length]=y;
                    length++;
                }
                T.createBalanceBiTreeFromArray(root, A,length);
                level=1;
                i=1;
                T.inOrderTraverse(root,level);
                cout<<endl;
                initArray(A);
                T.BiTreeToArray(root,A,i,length);
                cout<<"其樹狀圖為:"<<endl;
                T.LevelTraverse(root,A,length);
            break;
             case 6:
                i=1;
                initArray(A);
                T.AllAdjust(root);
                T.BiTreeToArray(root,A,i,length);
                cout<<"其樹狀圖為:"<<endl;
                T.LevelTraverse(root,A,length);
            break;
        }
        system("PAUSE");
        system("CLS");
        BalanceBiTree<int>::menu();
        cout<<"請輸入執行序號:";
        cin>>x;
    }
    if(root!=NULL)
    T.destory(root);
    return 0;
}
  • 執行截圖