您的位置:知识库 »

二叉搜索树(BST树)的简单实现

作者: Phinecos(洞庭散人)  来源: 博客园  发布时间: 2008-08-16 22:43  阅读: 1441 次  推荐: 0   原文链接   [收藏]  
#include <stdlib.h>
template
<typename T>
class CBinSTree;

template 
<typename T>
class CTreeNode
{//树节点类
public:
    CTreeNode(
const T& item,CTreeNode<T>* lptr = NULL,CTreeNode<T>* rptr = NULL):data(item),left(lptr),right(rptr)
    
{
    }

    CTreeNode
<T>* Left(void)
    
{
        
return left;
    }

    CTreeNode
<T>* Right(void)
    
{
        
return right;
    }

    friend 
class CBinSTree<T>;
public:
    T data;
//数据
private:
    CTreeNode
<T>* left;//左子树
    CTreeNode<T>* right;//右子树
}
;

template
<typename T>
class CBinSTree  
{//二叉搜索树类
public:
    CBinSTree();
    
virtual ~CBinSTree();
    CBinSTree(
const CBinSTree<T>& tree);
    CBinSTree
<T>& operator = (const CBinSTree<T>& rhs);
    CTreeNode
<T>* FindNode(const T& item,CTreeNode<T>* &parent)const;//寻找节点
    void PrintTree();//前序遍历树(非递归)
    void ClearTree();//清空树
    void Insert(const T& item);//插入数据
    void Delete(const T& item);//删除数据
    bool Contains(const T& item);//是否包含数据
    CTreeNode<T>* FindMin()const;//找最小值
    CTreeNode<T>* FindMax()const;//找最大值

protected:
    
//辅助函数区
    CTreeNode<T>* GetTreeNode(const T& item,CTreeNode<T>* lptr=NULL,CTreeNode<T>* rptr=NULL);//分配树节点
    void FreeTreeNode(CTreeNode<T>* p);//释放树节点
    void DeleteTree(CTreeNode<T>* t);//删除树
    CTreeNode<T>* CopyTree(CTreeNode<T>* t);//拷贝树
private:
    CTreeNode
<T> *root;//二叉搜索树树根
    int size;//树节点个数
}
;

 

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

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
template<typename T>
CBinSTree
<T>::CBinSTree()
{
    
this->root = NULL;
    
this->size = 0;
}

template
<typename T>
CBinSTree
<T>::CBinSTree(const CBinSTree<T>& tree)
{
    root 
= this->CopyTree(tree.root);
    
this->size = tree.size;
}

template
<typename T>
CBinSTree
<T>::~CBinSTree()
{
    
this->ClearTree();
}

template
<typename T>
CBinSTree
<T>& CBinSTree<T>::operator = (const CBinSTree<T>& rhs)
{
    
if(this==&rhs)
        
return *this;
    
this->ClearTree();
    root 
= this->CopyTree(rhs.root);
    size 
= rhs.size;
    
return *this;
}

template
<typename T>
CTreeNode
<T>* CBinSTree<T>::GetTreeNode(const T& item,CTreeNode<T>* lptr,CTreeNode<T>* rptr)
{
    CTreeNode
<T>* p;
    p 
= new CTreeNode<T>(item,lptr,rptr);
    
if(p==NULL)
    
{
        cerr
<<"分配内存失败!"<<endl;
        exit(
1);
    }

    
return p;
}

template
<typename T>
CTreeNode
<T>* CBinSTree<T>::FindMin()const
{
    CTreeNode
<T> *= root;
    
while(t->left!=NULL)
    
{
        t 
= t->left;
    }

    
return t;
}

template
<typename T>
CTreeNode
<T>* CBinSTree<T>::FindMax()const
{
    CTreeNode
<T> *= root;
    
while(t->right!=NULL)
    
{
        t 
= t->right;
    }

    
return t;
}

template
<typename T>
bool CBinSTree<T>::Contains(const T& item)
{
    CTreeNode
<T> *p;
    
return (this->FindNode(item,p)!=NULL);
}

template
<typename T>
CTreeNode
<T>* CBinSTree<T>::CopyTree(CTreeNode<T>* t)
{
    CTreeNode
<T> *newnode,*newlptr,*newrptr;
    
if(t==NULL)
        
return NULL;
    
if(t->Left()!=NULL)
        newlptr 
= CopyTree(t->Left());
    
else
        newlptr 
= NULL;
    
if(t->Right()!=NULL)
        newrptr 
= CopyTree(t->Right());
    
else
        newrptr 
= NULL;
    newnode 
= GetTreeNode(t->data,newlptr,newrptr);
    
return newnode;
}

template
<typename T>
void CBinSTree<T>::FreeTreeNode(CTreeNode<T>* p)
{
    delete p;
    p 
= NULL;
}

template
<typename T>
void CBinSTree<T>::DeleteTree(CTreeNode<T>* t)
{
    
if(t!=NULL)
    
{
        DeleteTree(t
->Left());
        DeleteTree(t
->Right());
        FreeTreeNode(t);
    }

}

template
<typename T>
void CBinSTree<T>::ClearTree()
{
    DeleteTree(root);
    root 
= NULL;
}

template
<typename T>
CTreeNode
<T>* CBinSTree<T>::FindNode(const T& item,CTreeNode<T>* &parent)const
{
    CTreeNode
<T> *= root;
    parent 
= NULL;
    
while(t!=NULL)
    
{
        
if(item==t->data)
            
break;
        
else
        
{
            parent 
= t;
            
if(item<t->data)
                t 
= t->Left();
            
else 
                t 
= t->Right();
        }

    }

    
return t;
}

template
<typename T>
void CBinSTree<T>::Insert(const T& item)
{
    CTreeNode
<T>* t = root,*parent = NULL,*newnode;
    
while(t!=NULL)
    
{
        parent 
= t;
        
if(item<t->data)
            t 
= t->Left();
        
else
            t 
= t->Right();
    }

    newnode 
= this->GetTreeNode(item);
    
if(parent==NULL)
        root 
= newnode;
    
else if(item<parent->data)
        parent
->left = newnode;
    
else
        parent
->right = newnode;
    size
++;
}

template
<typename T>
void CBinSTree<T>::Delete(const T& item)
{
    CTreeNode
<T> *pDNode,*pRNode,*pParNode;
    
if((pDNode = this->FindNode(item,pParNode))==NULL)
        
return;
    
if(pDNode->left==NULL)
        pRNode 
= pDNode->right;
    
else if(pDNode->right==NULL)
        pRNode 
= pDNode->left;
    
else
    
{
        CTreeNode
<T> *pParOfRNode = pDNode;
        pRNode 
= pDNode->left;
        
while(pRNode->right!=NULL)
        
{
            pParOfRNode 
= pRNode;
            pRNode 
= pRNode->right;
        }

        
if(pParOfRNode==pDNode)
        
{
            pRNode
->right = pDNode->right;
        }

        
else
        
{
            pParOfRNode
->right = pRNode->left;
            pRNode
->left = pDNode->left;
            pRNode
->right = pDNode->right;
        }

    }

    
if(pParNode==NULL)
        root 
= pRNode;
    
else if(pDNode->data<pParNode->data)
        pParNode
->left = pRNode;
    
else
        pParNode
->right = pRNode;
    
this->FreeTreeNode(pDNode);
    
this->size--;

}

template
<typename T>
void CBinSTree<T>::PrintTree()
{
    stack
<CTreeNode<T>* > s;
    CTreeNode
<T>* p = root;
    
while (p!=NULL || !s.empty())
    
{
        
while (p!=NULL)             //遍历左子树
        {
            cout
<<p->data<<endl;
            s.push(p);
            p
=p->Left();
        }
//endwhile
        
        
if (!s.empty())
        
{
            p
=s.top();
            s.pop();
            p
=p->Right();            //通过下一次循环实现右子树遍历
        }
//endif   
    }

}

 

// test.cpp : Defines the entry point for the console application.
//

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

CBinSTree
<int>* MakeSampleTree()
{//示例BST树
    CBinSTree<int> *tree1 = new CBinSTree<int>();
    
int a = 5;
    tree1
->Insert(a);
    tree1
->Insert(30);
    tree1
->Insert(65);
    tree1
->Insert(25);
    tree1
->Insert(35);
    tree1
->Insert(50);
    tree1
->Insert(10);
    tree1
->Insert(28);
    tree1
->Insert(26);
    tree1
->Insert(33);
    
return tree1;
}


int main(int argc, char* argv[])
{
    CBinSTree
<int> *tree1 = MakeSampleTree();
    tree1
->PrintTree();
    std::cout
<<"删除节点30:"<<endl;
    tree1
->Delete(30);
    tree1
->PrintTree();
    cout
<<tree1->Contains(40)<<endl;
    CTreeNode
<int> *= tree1->FindMin();
    cout
<<p->data<<endl;
    
return 0;
}

0
0

热门文章

    最新文章

      最新新闻

        热门新闻