码迷,mamicode.com
首页 > 其他好文 > 详细

二叉排序树(Binary Sort Tree)

时间:2014-07-01 22:24:39      阅读:242      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   数据   2014   

二叉排序树(Binary Sort Tree)又称二叉查找树,是一种排序和查找都很有用的特殊二叉树。
BST 满足 左节点的值<根节点的值<右节点的值。根据这个原理,我们可以推断:BST的中序遍历必定是严格递增的。

如图一棵二叉树,是一棵BST。我们可以明显看到他的中序遍历为09,17,23,45,53,60,70,75,78,88,94。(因为左<中<右)

bubuko.com,布布扣

下面是BST的实现,包括BST的插入,创建,删除,遍历

//BST.h
#include<iostream>
using namespace std;
template<typename T>
struct node
{
    T key;
    //char word;
};
template<typename T>
struct BSTNode
{
    node<T> data;
    BSTNode<T> *lchild;
    BSTNode<T> *rchild;
};
template<typename T>
class BSTree
{
private:
    BSTNode<T> *bt;//根指针
public:
    BSTree();//构造函数
    ~BSTree();//析构函数
    BSTNode<T>* & GetRoot();//得到跟节点
    void Clear(BSTNode<T>* &p);//删除节点,释放空间
    bool BSTInsert(BSTNode<T>* &p,T key);//在p指向的二叉树中有序插入 数据元素为key的节点
    void Create(int n);//创建含有n个元素的BST
    void PreTraBST(BSTNode<T> *p);//前序遍历
    void InTraBST(BSTNode<T> *p);//中序遍历,输出的BST是从小到大排列的
    void SearchBST(BSTNode<T> *p,T key);//在p指向的二叉树中查找 是否存在数据元素key
    int Delete(BSTNode<T> * &p);//删除节点p
    int DeleteBST(BSTNode<T>* &p,T key);//在p指向的BST中删除数据元素key,并保证删除后的二叉树还是BST
};
template<typename T>
BSTree<T>::BSTree()
{
    bt=NULL;
}
template<typename T>
BSTree<T>::~BSTree()
{
    BSTNode<T> *p;
    p=bt;
    Clear(p);
}
template<typename T>
BSTNode<T>* & BSTree<T>::GetRoot()
{
    return bt;
}
template<typename T>
void BSTree<T>::Clear(BSTNode<T> * &p)
{
    if(p)
    {
        Clear(p->lchild);
        Clear(p->rchild);
    }
    getchar();
    delete p;
    cout<<"删除节点"<<p<<"的空间"<<endl;
}
template<typename T>
bool BSTree<T>::BSTInsert(BSTNode<T>* &p,T key)//在p指向的二叉树中有序插入数据元素key
{
    if(p==NULL) //p为空树,创建数据元素为key的新节点,并将p指向该节点
    {
        BSTNode<T> *s=new BSTNode<T>;
        s->data.key=key;
        s->lchild=s->rchild=NULL;
        p=s;
        return true;
    }
    else if(key>p->data.key)//key 大于节点p->data.key,递归遍历右子树。BST的右子树一定大于左子树
        BSTInsert(p->rchild,key);
    else if(key<p->data.key)//key 小于节点p->data.key,遍历左子树。
        BSTInsert(p->lchild,key);
    else if(key==p->data.key)
    {
        cout<<"插入数据已存在"<<endl;
        return false;
    }
}
template<typename T>
void BSTree<T>::Create(int n)
{
    T key;
    bt=NULL; 
    cout<<"输入"<<n<<"个不同的数据元素"<<endl;
    for(int i=0;i<n;i++)
    {
        cin>>key;
        BSTInsert(bt,key);
    }
}
template<typename T>
void BSTree<T>::PreTraBST(BSTNode<T> *p)
{
    if(p)
    {
        cout<<p->data.key<<" ";
        PreTraBST(p->lchild);
        PreTraBST(p->rchild);
    }
}
template<typename T>
void BSTree<T>::InTraBST(BSTNode<T> *p) //中序输出时数据元素一定是按升序排列的
{
    if(p)
    {
        InTraBST(p->lchild);
        cout<<p->data.key<<" ";
        InTraBST(p->rchild);
    }

}
template<typename T>
void BSTree<T>::SearchBST(BSTNode<T> *p,T key)//在BST中查找数据元素key 是否存在,存在则找出其中的p,并且删除
{
    if(p==NULL||p->data.key==key)
    {
        if(p==NULL)
        {
            cout<<"查找的数据元素不存在"<<endl;
        }
        else if(p->data.key==key)
        {
            cout<<"找到数据元素"<<key<<endl;
        }
    }
    else if(key>p->data.key)
    {
        SearchBST(p->rchild,key);
    }
    else if(key<p->data.key)
    {
        SearchBST(p->lchild,key);
    }
        
}
template<typename T>
int BSTree<T>::Delete(BSTNode<T>* &p)//删除节点p
{
    BSTNode<T> *q,*s;
    if(p->rchild==NULL)//待删除的节点p没有右子树
    {
        q=p;
        p=p->lchild;
        cout<<"成功删除"<<endl;
        delete q;
        
    }
    else if(p->lchild==NULL)//待删除的节点p没有左子树
    {
        q=p;
        p=p->rchild;
        cout<<"成功删除"<<q->data.key<<endl;
        delete q;
        
    }
    else if(p->lchild==NULL&&p->rchild==NULL)
    {
        
        delete p;
        cout<<"成功删除"<<endl;
    }
    else//待删除的节点p的左右节点都存在
    {
        q=p;
        s=p->lchild;
        while(s->rchild)//在p节点的左子树中寻找其前驱节点。即最右节点。
        {
            q=s;
            s=s->rchild;//最终s指向待删除节点的前驱节点
        }
        p->data=s->data;//将前驱节点赋值给p节点
        if(q!=p)
            q->rchild=s->lchild;
        else q->lchild=s->lchild;
        delete s;
        cout<<"成功删除"<<endl;    
    }
    return true;
}
template<typename T>
int BSTree<T>::DeleteBST(BSTNode<T>* &p,T key)
{
    if(p==NULL)
    {
        cout<<"二叉树为空,无法删除"<<endl;
        return false;
    }
    else
    {
        if(key==p->data.key)
            return Delete(p);
        else if(key>p->data.key)
            return DeleteBST(p->rchild,key);
        else
            return DeleteBST(p->lchild,key);
    }
}
//BST-main.cpp
#include<iostream>
using namespace std;
#include"BST.h"
int main(void)
{
    int n,key,flag;
    BSTree<int> bst;

    cout<<"输入二叉树的数据元素个数:";

    cin>>n;
    bst.Create(n);//Create创建的是一个排序二叉树
    cout<<"先序遍历输出:";
    bst.PreTraBST(bst.GetRoot());
    cout<<endl;

    cout<<"中序遍历输出:";//中序遍历一定是有序的
    bst.InTraBST(bst.GetRoot());
    cout<<endl;

    cout<<"输入要查找的元素:";
    cin>>key;
    bst.SearchBST(bst.GetRoot(),key);

    flag=1;
    while(flag)
    {
        cout<<"输入要删除的元素(-1为结束标志):";
        cin>>key;
        if(key!=-1)
        {
            bst.DeleteBST(bst.GetRoot(),key);
        }
        else
            flag=0;

        cout<<"先序遍历输出:";
        bst.PreTraBST(bst.GetRoot());
        cout<<endl;

        cout<<"中序遍历输出:";//中序遍历一定是有序的
        bst.InTraBST(bst.GetRoot());
        cout<<endl;
    }
    getchar();
}

测试结果如下:

bubuko.com,布布扣

关于BST 删除数据元素的理解

1.待删除的节点p没有右子树  p->rchild==NULL

bubuko.com,布布扣

2.待删除的节点p没有左子树 p->lchild==NULL

bubuko.com,布布扣

3.左右子节点都不存在  p->lchild==NULL&&p->rchild==NULL

直接删除

 

4.左右子节点都存在   p->lchild!=NULL&&p->rchild!=NULL

4.1   q!=p  其中s指向待删除节点的前驱节点,然后用77替换78,并将75指向76

bubuko.com,布布扣      

4.2  p==q  将节点70赋值给节点80

bubuko.com,布布扣

 

 

 

 

二叉排序树(Binary Sort Tree),布布扣,bubuko.com

二叉排序树(Binary Sort Tree)

标签:style   blog   http   color   数据   2014   

原文地址:http://www.cnblogs.com/qianwen/p/3816574.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!