1. 程式人生 > >二叉搜尋樹(BST樹)

二叉搜尋樹(BST樹)

二叉搜尋樹

文章目錄

1,定義

二叉查詢樹(Binary Search Tree),又名二叉搜尋樹或二叉排序樹。可以是一顆空樹,或者是具有下列性質的二叉樹:

(1)若它的左子樹不空,則左子樹上所有結點的值均小於它的根結點的值;

(2)若它的右子樹不空,則右子樹上所有結點的值均大於它的根結點的值;

2,C++實現二叉樹的基本操作

#include<iostream>
#include<queue>
#include<stack>
using namespace std;
/*BST樹的結點型別*/
template <typename T>
struct BSTNode
{
    BSTNode(T data=T()):mdata(data),mleft(NULL),mright(NULL){}//T data=T():0的初始化
    T mdata;
    BSTNode<T>*mleft;
    BSTNode<T>*mright;
};

template<typename T>
class BSTree
{
public:
    BSTree():mroot(NULL){}
    ~BSTree(){}
    /*向BST樹中插入資料:
    過程為:
	若b是空樹,則將val所指結點作為根結點插入,否則:
	若val等於b的根結點的資料域之值,則返回,否則:
	若val小於b的根結點的資料域之值,則把val所指結點插入到左子樹中,否則:
	把val所指結點插入到右子樹中
    */
    void insert(const T&val)
    {
        if(mroot==NULL)
        {
            mroot=new BSTNode<T>(val);
            return;
        }
        BSTNode<T>*ppre=mroot;
        BSTNode<T>*pcur=mroot;
        while(pcur!=NULL)
        {
            ppre=pcur;
            if(val<pcur->mdata)
            {
               pcur=pcur->mleft;
            }
            else if(val>pcur->mdata)
            {
                pcur=pcur->mright;
            }
            else
            {
                return;
            }
        }
        if(val<ppre->mdata)
        {
            ppre->mleft=new BSTNode<T>(val);
        }
        else
        {
            ppre->mright=new BSTNode<T>(val);
        }
    }
    /*BST樹的結點刪除
    在二叉排序樹刪去一個結點,分三種情況討論:
	若*p結點為葉子結點,即PL(左子樹)和PR(右子樹)均為空樹。由於刪去葉子結點不破壞整棵樹的結構,則只需修改其雙親結點的指標即可。
	若*p結點只有左子樹PL或右子樹PR,此時只要令PL或PR直接成為其雙親結點*f的左子樹或右子樹即可,作此修改也不破壞二叉排序樹的特性。
	若*p結點的左子樹和右子樹均不空。在刪去*p之後,為保持其它元素之間的相對位置不變,可按中序遍歷保持有序進行調整,可以有兩種做法:其一是令*p的左子樹為*f的左子樹,*s為*f左子樹的最右下的結點,而*p的右子樹為*s的右子樹;其二是令*p的直接前驅(或直接後繼)替代*p,然後再從二叉排序樹中刪去它的直接前驅(或直接後繼)。在二叉排序樹上刪除一個結點的演算法如下:
    
    */
    void remove(const T&val)
    {
        if(mroot==NULL)
        {
            return;
        }
        BSTNode<T>*ppre=NULL;
        BSTNode<T>*pcur=mroot;
        while(pcur!=NULL)
        {
            if(val<pcur->mdata)
            {
                ppre=pcur;
                pcur=pcur->mleft;
            }
            else if(val>pcur->mdata)
            {
                ppre=pcur;
                pcur=pcur->mright;
            }
            else
            {
               break;
            }
        }
        if(pcur==NULL)
        {
            return;
        }
        if(pcur->mleft!=NULL&&pcur->mright!=NULL)
        {
            ppre=pcur;
            BSTNode<T>*pdel=pcur->mleft;
            ppre=pcur;
            BSTNode<T>*pdel=pcur->mleft;
            while(pdel->mright!=NULL)
            {
                ppre=pcur;
                pdel=pdel->mright;
            }
            //pdel為待刪除的結點
            pcur->mdata=pdel->mdata;
            pcur=pdel;
        }
        //開始刪除結點,記錄當前待刪除結點的自孩子
        BSTNode<T>*pchild=NULL;
        if(pcur->mleft!=NULL)
        {
            pchild=pcur->mright;
        }
        else if(pcur->mright!=NULL)
        {
            pchild=pcur->mleft;
        }
        //pcur 開始刪除操作
        if(ppre==NULL)
        {
            mroot=pchild;
        }
        else if(pcur->mdata<=ppre->mdata)
        {
            ppre->mleft=pchild;
        }
        else
        {
            ppre->mright=pchild;
        }
        delete pcur;
    }
    /*BST樹的查詢*/
    bool query(const T&val)
    {
        BSTNode<T>*pcur=mroot;
        while(pcur!=NULL)
        {
            if(val<pcur->mdata)
            {
                pcur=pcur->mleft;
            }
            else if(val>pcur->mdta)
            {
                pcur=pcur->mright;
            }
            else
            {
                return true;
            }
        }
        return false;
    }
    /*層序遍歷*/
    void level()
    {
        cout<<"層序遍歷為:";
        queue<BSTNode<T>*>QUE;
        QUE.push(mroot);
        while(!QUE.empty())
        {
            BSTNode<T>*pcur=QUE.front();
            cout<<pcur->mdata<<" ";
            if(pcur->mleft!=NULL)
            {
               QUE.push(pcur->mleft);
            }
            if(pcur->mright!=NULL)
            {
               QUE.push(pcur->mright);
            }
            QUE.pop();
        }
        cout<<endl;
    }
    /*前序遍歷*/
   //遞迴實現
    void preOrder() 
    {
       preOrder(mroot);
    }
   //非遞迴實現
    void preOrder1()
    {
        if(mroot==NULL)
        {
            return;
        }
        cout<<"前序遍歷為:";
        stack<BSTNode<T>*>Stack;
        BSTNode*pcur=mroot;
        while(pcur!=NULL||!Stack.empty())
        {
            while(pcur!=NULL)
            {
                cout<<pcur->mdata<<" ";
                Stack.push(pcur);
                pcur=pcur->mleft;
            }
            if(!Stack.empty())
            {
                pcur=Stack.top();
                Stack.pop()
                pcur=pcur->mright;
            }
        }
        cout<<endl;
    }
    /*中序遍歷*/   
    //遞迴實現
   void inOrder() 
    {
       inOrder(mroot);
    }
    //非遞迴實現
    void inOrder1()
    {
        cout<<"中序遍歷為:";
        if(mroot==NULL)
        {
            return;
        }
        stack<BSTNode<T>*>Stack1;
        BSTNode<T>*pcur=mroot->mleft;
        Stack1.push(mroot);
        while(pcur!=NULL||!Stack1.empty())
        {
            while(pcur!=NULL)
            {
                Stack1.push(pcur);
                pcur=pcur->mleft;
            }
            pcur=Stack1.top();
            Stack1.pop();
            cout<<pcur->mdata<<" ";
            pcur=pcur->mright;
        }
        cout<<endl;
    }
    /*後序遍歷*/
    //遞迴實現
    void lastOrder() 
    {
        lastOrder(mroot);
    }
    //非遞迴實現
    void lastOrder1()
    {
        if(mroot==NULL)
        {
            return;
        }
        cout<<"後序遍歷為:";
        stack<BSTNode<T>*>Stack2;
        BSTNode<T>*ppre=NULL;
        BSTNode<T>*pcur=mroot;
        while(pcur!=NULL||!Stack2.empty())
        {
            while(pcur!=NULL)
            {
                Stack2.push(pcur);
                pcur=pcur->mleft;
            }
            pcur=Stack2.top();
            if(pcur->mright==NULL||pcur->mright==ppre)
            {
                cout<pcur->mdata<<" ";
                ppre=pcur;
                Stack2.pop();
                pcur=NULL;
            }
            else
                pcur=pcur->mright;
        }
        cout<<endl;
    }
private:
    BSTNode<T>*mroot;//指向BST樹的根節點
    
    void preOrder(BSTNode<T>*pnode)
    {
        if(pnode!=NULL)
        {
            cout<<pnode->mdata<<" ";
            preOrder(pnode->mleft);
            preOrder(pnode->mright);
        }
    }
    void inOrder(BSTNode<T>*pnode1)
    {
        if(pnode1!=NULL)
        {
            inOrder(pnode1->mleft);
            cout<<pnode1->mdata<<" ";
            inOrder(pnode1->mright);
        }
    }
    void lastOrder(BSTNode<T>*pnode2)
    {
        if(pnode2!=NULL)
        {
            lastOrder(pnode2->mleft);
            lastOrder(pnode2->mright);
            cout<node2->mdata<<" ";
        }
    }
}

函式實現:

int main()
{
    BSTree<int>tree;
    tree.insert(57);
    tree.insert(24); 
    tree.insert(90);
    tree.insert(8);
    tree.insert(35);
    tree.insert(68);
    tree.insert(124);
    tree.insert(12); 
    tree.insert(46);
    tree.insert(79);
    tree.insert(234);
    
    //tree.remove(35);
    
    tree.level();
    tree.preOrder1();
    tree.inOrder();
    tree.lastOrder();
    return 0;
}

結果:
在這裡插入圖片描述