0x55AA 发表于 2014-12-8 18:06:32

【C++】C++模板实现的二叉排序(查找)树

二叉排序树定义:
二叉排序树是这样的树,结点左边的值都小于结点的值,结点右边的值都大于结点的值,所以按照二叉树的中序遍历的话,得到的的将是按顺序排列的值。
二叉排序树的主要操作:
1:插入
插入的操作非常简单,从根结点开始,如果插入值大于根节点值,则向右遍历,如果小于根节点值,则想左遍历,知道遇到一个叶子结点为止。按插入值大于叶子则将插入值作为叶子结点的右孩子,否则左孩子。中间过程中如果遇到跟插入值相等的,则插入失败。
2:删除
关于有三种情况需要不同对待。
<1>如果是叶子结点,那么直接删除就行(注意相关的孩子指针要变成NULL)。
<2>如果要删除的结点只有左孩子或者右孩子,这样也好办,我们只需要把相应的孩子赋值          给待删除结点的双亲结点的孩子指针即可,孙子升级当儿子。
<3>如果要删除的结点既有左孩子,又有右孩子,那么情况就稍微有点麻烦,在这里我们可以采取两种策略来实现,第一种是“前驱不动,移动右孩子法”,第二种是“右孩子不动,移动前驱法”。具体如下图所示:

3:遍历
遍历采用递归方法,遍历的实现就很简单了。
4:清除
在清除树的所有结点的时候,采取了递归思想,判断左孩子是否为空,如果不空则清空做孩子;再判断右孩子是否为空,不为空则清空右孩子;只有当结点左右孩子结点都为空的时候,才释放该结点的空间。
5:查找
查找要利用二叉排序树的自身优点来进行,每次根据与结点的比较结果选择再继续跟左孩子比较还是跟右孩子比较。

实现代码:
BSTrees.h//BSTrees.h
#ifndef DDXX_BSTREES_H
#define DDXX_BSTREES_H
#include <iostream>
using namespace std;
template<typename Type>
class BSTrees
{
public:
        BSTrees();
        ~BSTrees();
public:
        struct Node
        {
                Type        e;
                Node*        leftChild;
                Node*        rightChild;
                Node()
                {
                }
                Node(Type _e)
                {
                        e                        = _e;
                        leftChild        = NULL;
                        rightChild        = NULL;
                }
        };
public:
        bool        insert(Type e);
        bool        erase1(Type e);
        bool        erase2(Type e);
        void        clear();
        bool        isEmpty();
        int                getLength();
        Node*        find(Type e);
        Node*        getRoot();
        Node*        getParent(Node* p);
        void        traverse(Node* ptr);
private:
        void        clears(Node* &p);
private:
        Node*        m_root;
        int                m_Length;
};

template<typename Type> BSTrees<Type>::BSTrees()
{
        m_root = NULL;
        m_Length = 0;
}

template<typename Type> bool BSTrees<Type>::insert(Type e)
{
        Node* ptr = new Node(e);
        if ( ptr == NULL )
        {
                cout<<"Allocate memory for the element failed"<<endl;
                return false;
        }

        if( m_root == NULL)
        {
                m_root = ptr;
                m_Length++;
                return true;
        }

        Node* p                        = m_root;
        Node* pParent        = m_root;
        while( p != NULL)
        {
                if( e == p->e)
                {
                        cout<<"the element is already exist"<<endl;
                        return false;
                }

                pParent = p;
                if( e > p->e)
                {
                        p = p->rightChild;
                }
                else
                {
                        p = p->leftChild;
                }
        }
       
        if( e < pParent->e )
        {
                pParent->leftChild = ptr;
        }
        if( e > pParent->e)
        {
                pParent->rightChild = ptr;
        }

        m_Length++;
        return true;
}

template<typename Type> bool BSTrees<Type>::erase1(Type e)
{
        Node *p = find(e);
        if ( p == NULL )
        {
                cout<<"There's no this element to delete"<<endl;
                return false;
        }

        if ( p->leftChild == NULL)
        {
                Node* pParent = getParent(p);
                if( pParent->leftChild == p )
                        pParent->leftChild = p->rightChild;
                else
                        pParent->rightChild = p->rightChild;
                delete p;
                p = NULL;

                m_Length--;
                return true;
        }

        if ( p->rightChild == NULL)
        {
                Node* pParent = getParent(p);
                if( pParent->leftChild == p)
                        pParent->leftChild = p->leftChild;
                else
                        pParent->rightChild = p->leftChild;
                delete p;
                p = NULL;

                m_Length--;
                return true;       
        }

        if ( p->leftChild != NULL && p->rightChild != NULL)
        {
                Node* pParent = getParent(p);
                Node* pPre = p->leftChild;
                Node* ptmp = pPre;
                while( pPre->rightChild != NULL )
                {
                        ptmp = pPre;
                        pPre = pPre->rightChild;
                }
                if( ptmp != pPre)
                {        ptmp->rightChild = pPre->leftChild;
                        pPre->leftChild = p->leftChild;
                        pPre->rightChild = p->rightChild;
                }
                else
                        pPre->rightChild = p->rightChild;

                if( pParent == NULL )
                        m_root = pPre;
                else
                        if( pParent->leftChild == p)
                                pParent->leftChild = pPre;
                        else
                                pParent->rightChild = pPre;
               
                delete p;
                p = NULL;

                m_Length--;
                return true;
        }
       
}

template<typename Type> bool        BSTrees<Type>::erase2(Type e)
{
        Node *p = find(e);
        if ( p == NULL )
        {
                cout<<"There's no this element to delete"<<endl;
                return false;
        }

        if ( p->leftChild == NULL)
        {
                Node* pParent = getParent(p);
                if( pParent->leftChild == p )
                        pParent->leftChild = p->rightChild;
                else
                        pParent->rightChild = p->rightChild;
                delete p;
                p = NULL;

                m_Length--;
                return true;
        }

        if ( p->rightChild == NULL)
        {
                Node* pParent = getParent(p);
                if( pParent->leftChild == p)
                        pParent->leftChild = p->leftChild;
                else
                        pParent->rightChild = p->leftChild;
                delete p;
                p = NULL;

                m_Length--;
                return true;       
        }
        if( p->leftChild != NULL && p->rightChild != NULL)
        {
                Node* pParent = getParent(p);
                Node* ptr = p->leftChild;
                while( ptr->rightChild != NULL )
                        ptr = ptr->rightChild;
                ptr->rightChild = p->rightChild;

                if( pParent == NULL )
                        m_root = p->leftChild;
                else
                        if(pParent->leftChild == p)
                                pParent->leftChild = p->leftChild;
                        else
                                pParent->rightChild = p->leftChild;
                delete p;
                p = NULL;
                m_Length--;
                return true;
        }
}

template<typename Type> void        BSTrees<Type>::clear()
{
        if( m_root == NULL )
                return;
        clears(m_root);
        m_root = NULL;
}

template<typename Type> void       BSTrees<Type>::clears(Node* &p)
{
        if(p->leftChild != NULL)
        {
                clears(p->leftChild);
                p->leftChild = NULL;
        }
        if(p->rightChild != NULL)
        {
                clears(p->rightChild);
                p->rightChild = NULL;
        }
        delete p;
        p = NULL;
        m_Length--;
       
}
template<typename Type> typename BSTrees<Type>::Node* BSTrees<Type>::getRoot()
{
        return m_root;
}
template<typename Type> int                BSTrees<Type>::getLength()
{
        return m_Length;
}
template<typename Type> typename BSTrees<Type>::Node* BSTrees<Type>::getParent(Node* p)
{
        if( p == m_root)
                return NULL;
        Node* ptr = m_root;
        Node* ptf = ptr;
        while( ptr != NULL )
        {
                if ( ptr->e == p->e )
                        return ptf;
                if ( ptr->e > p->e )
                {
                        ptf = ptr;
                        ptr = ptr->leftChild;
                }
                else
                {
                        ptf = ptr;
                        ptr = ptr->rightChild;
                }
        }

}

template<typename Type> typename BSTrees<Type>::Node* BSTrees<Type>::find(Type e)
{
        Node* ptr = m_root;

        while(ptr != NULL)
        {
                if ( ptr->e == e )
                        return ptr;
                if ( ptr->e > e )
                        ptr = ptr->leftChild;
                else
                        ptr = ptr->rightChild;
        }
        if ( ptr == NULL )
                return NULL;
}

template<typename Type> void BSTrees<Type>::traverse(Node* ptr)
{
        if( ptr == NULL )
                return;
        if( ptr->leftChild != NULL )
                traverse(ptr->leftChild);
        cout<<"Element value:"<<ptr->e<<endl;
        if( ptr->rightChild != NULL )
                traverse(ptr->rightChild);
}

template<typename Type> BSTrees<Type>::~BSTrees()
{
        clear();
}
#endifmain.cpp//main.cpp
#include <iostream>
#include "BSTrees.h"
using namespace std;
void main()
{
        cout<<"************************test BSTree insert***********************"<<endl;
        BSTrees<int> Bst;
        int Arr = {6,2,8,4,10,0,12,16,14};
        for (int i=0;i<9;i++)
                Bst.insert(Arr);
        Bst.traverse(Bst.getRoot());
        cout<<"Tree's length is:"<<Bst.getLength()<<endl;

        cout<<"************************test BSTree erase1***********************"<<endl;
        //Bst.erase1(6);
        //Bst.erase1(16);
        //Bst.erase1(10);
        //Bst.erase1(8);
        Bst.erase2(6);
        Bst.erase2(16);
        Bst.erase2(10);
        Bst.erase2(8);
        Bst.traverse(Bst.getRoot());
        cout<<"Tree's length is:"<<Bst.getLength()<<endl;

        Bst.clear();
        Bst.traverse(Bst.getRoot());
        cout<<"Tree's length is:"<<Bst.getLength()<<endl;
}测试结果:

laxect 发表于 2014-12-8 20:31:27

这是在屠版么。。。
页: [1]
查看完整版本: 【C++】C++模板实现的二叉排序(查找)树