用c++实现一个二叉排序树

二叉排序树又称二叉查找树(Binary Search Tree)。其定义为:二叉排序树或者收空树,或者是满足如下性质的二叉树。
(1)若它的左子树非空,则左子树上所有节点的值均小于根节点的值。
(2)若它的右子树非空,则右子树上所有节点的值均大于根节点的值。
(3)左右子树本身又各是一颗二叉排序树。
二叉排序树
二叉排序树数据结构如下:

//节点类定义
class Node
{
    int data;
    Node *parent;   //父节点
    Node *left;        //左节点
    Node *right;     //右节点
    public:
        Node():data(-1),parent(NULL),left(NULL),right(NULL){};
        Node(int num):data(num),parent(NULL),left(NULL),right(NULL){};
}

二叉排序树类的定义:

class Tree
{
    public:
        Tree(int num[],int len);  //插入num数组的前len个数据
        void insertNode1(int data);  //插入数据,用递归的方式
        void insertNode(int data);   //插入数据,用非递归的方式
        Node *searchNode(int data); //查找节点
        void deleteNode(int data);    //删除节点以及子树
     private:
         void insertNode(Node* current,int data); //递归插入方法
         Node* searchNode(Node* current,int data); //递归查找方法
         void deleteNode(Node* current);   //递归删除方法
    private:
        Node *root; //根节点
}

在private中的三个方法主要是为了封装性的考虑,指针root是私有成员变量,于是在public中使用递归方法的三个函数都只能有一个参数data,然而,这里只含有一个参数是无法进行递归计算的。因此他们内部调用了这三个private中的方法。
接下来说明各个方法的实现。
1,创建二叉排序树的方法(在构造函数中)

Tree::Tree(int num[],int len)
{
    root=new Node(num[0]);//建立root节点
    for(int i=1;i<len;i++)
    {
        insertNode1(num[i]);
        /*insertNode(num[i]);*/
    }
};

2,插入节点操作

//以非递归的方式
void Tree::insertNode1(int data)
{
    Node *p,*par;
    Node *newNode=new Node(data);
    p=par=root;
    while(p!=NULL)
    {
        par=p;
        if(data>p->data)
            p=p->right;
            else if(data<p->data)
                p=p->left;
        else if(data==p->data)
            {
                delete newNode;  //不能插入重复数据
                return;
            }
    }
    newNode->parent=par;
    if(par->data > newNode->data)
        par->left=newNode;
    else
        par->right=newNode;
}

它分为以下步骤:
(1)创建节点
(2)查找新建节点的插入位置
(3)把新建点插入目标节点的正确位置。

insertNode()内部调用private函数insertNode(),使用递归方式插入。

//插入数据为参数data的节点,调用递归插入的方法
void Tree::insertNode(int data)
{
    if(root!=NULL)
    {
        insertNode(root,data);
    }
}
//递归插入方法
void Tree::insertNode(Node* current,int data)
{
    //如果data小于当前节点数据,则在当前节点的左子树插入
    if(data<current->data)
    {
        if(current->left==NULL)//若不存在,则插入到左节点
        {
            current->left=new Node(data);
            current->left->parent=current;
        }
        else
            insert(current->left,data);
    }
    //如果data大于当前节点,则在右子树中插入
    else if(data>current->data)
    {
        if(current->right==NULL)
        {
            current->right=new Node(data);
            current->right->parent=current;
        }
        else
            insertNode(current->right,data);
    }
    return;   //data等于当前节点数据时,不插入
}

3,查找节点

Node* Tree::searchNode(Node* current,int data)
{
    //如果data小于当前节点,则搜索左子树
    if(data<current->data)
    {
        if(current->left==NULL)//如果不存在左子树
            return NULL;
        return searchNode(current->left,data);
    }
    /*如果data大于当前节点,则递归搜索其右子树*/
    else if(data>current->data)
    {
        if(current->right==NULL)
            return NULL;
        return searchNode(current->right,data);
    }
    //如果相等,则返回current
    return current;
}

4,删除节点

void Tree::deleteNode(int data)
{
    Node *current=NULL;
    current=searchNode(data);   //查找节点
    if(current!=NULL)
    {
        deleteNode(current);
    }
}
void Tree::deleteNode(Node *current)
{
    if(current->left!=NULL) 
        deleteNode(current->left);
    if(current->right!=NULL)
        deleteNode(current->right);
    if(current->parent==NULL)
    {
             /*如果current是根节点,把root置空*/
        delete current;
        root=NULL;
        return;
    }
    //将current父亲节点的相应指针置空
    if(current->parent->data>current->data)
        current->parent->left=NULL;
    else
        current->parent->right=NULL;
    //最后删除此节点
    delete current;
}
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值