二叉查找树

二叉查找树定义
二叉查找是是满足以下条件的二叉树
1.对于树中每个节点x,其左子树中所有节点的值均小于x;
2.对于树中每个节点x,其右子树中所有节点的值均大于x;

二叉查找树的基本操作
1.findMin 与findMax
(1) 要执行findMin,只要从根开始,一直沿着左节点往下找,直到子节点等于NULL为止。
(2)要执行findMax,只要从根开始,一直沿着右节点往下找,直到子节点等于NULL为止。
查找最大与最小元素

2.插入操作
插入的节点肯定是树的叶子,因此
(1)首先判断待插入值与当前节点值得大小关系
(2)如果小于当前节点值,则在左节点寻找插入点。
(3)如果大于当前节点,则在右节点寻找插入点。
(4)如果等于当前节点,则什么都不干
代码如下

//注意使用的是指针的引用,也可以使用指针的指针
template<class T>
void BinarySearchTree<T>::_insert(const T& x, BinaryNode<T>* & p)
{
    if (p == NULL)
    {
        p = new BinaryNode<T>(x, NULL, NULL);
    }
    else if (x < p->value)
    {
        _insert(x, p->left);
    }
    else if (x > p->value)
    {
        _insert(x, p->right);
    }
}

3.删除操作
分为3种情况
(1)如果待删除节点是叶子节点,则直接删除。
(2)如果待删除节点只有一个孩子,则用孩子节点替换要删除的节点。
(3)如果待删除节点有两个孩子,则以该节点右子树中最小的数据项替换该节点的数据项,再删除右子树中数据项最小的节点。
这里写图片描述

#include<iostream>
#include<vector>
#include<string>


using namespace std;
template<class T>
struct BinaryNode
{
public:
    T value;
    BinaryNode<T>* left;
    BinaryNode<T>* right;
    BinaryNode(const T& x, BinaryNode<T>* l,BinaryNode<T>*r) :value(x),left(l),right(r){}

};



template <class T>
class BinarySearchTree
{
public:
    BinarySearchTree() :root(NULL){} //构造函数
    //析构函数
    ~BinarySearchTree(){} 

    const BinaryNode<T>* findMin() const;
    const BinaryNode<T>* findMax() const;

    bool isEmpty() const{ return root == NULL ? true : false; };

    void printTree() const{ _printTree(root); };
    void insert(const T& x);

    void remove(const T&x){ _remove(x, root); };
    void makeEmpty(){ _makeEmpty(root); };



private:
    BinaryNode<T>* root;
    void _insert(const T&, BinaryNode<T>* & p);
    void _remove(const T&, BinaryNode<T>*&);
    BinaryNode<T>* _find(const T&, BinaryNode<T>*);
    void _printTree(BinaryNode<T>*)const;
    void _makeEmpty(BinaryNode<T>*&);
};

template<class T>
const  BinaryNode<T>* BinarySearchTree<T>::findMin() const
{
    if (root == NULL) return NULL;
    auto p = root;
    while (p->left != NULL)
    {
        p = p->left;
    }
    return p;
}

template<class T>
const  BinaryNode<T>* BinarySearchTree<T>::findMax() const
{
    if (root == NULL) return NULL;
    auto p = root;
    while (p->right != NULL)
    {
        p = p->right;
    }
    return p;
}

//注意使用的是指针的引用,也可以使用指针的指针
template<class T>
void BinarySearchTree<T>::_insert(const T& x, BinaryNode<T>* & p)
{
    if (p == NULL)
    {
        p = new BinaryNode<T>(x, NULL, NULL);
    }
    else if (x < p->value)
    {
        _insert(x, p->left);
    }
    else if (x > p->value)
    {
        _insert(x, p->right);
    }
}
template<class T>
void BinarySearchTree<T>::insert(const T&x)
{
    _insert(x, root);
}

template<class T>
void BinarySearchTree<T>::_remove(const T& x, BinaryNode<T>*& p)
{
    if (p == NULL)
    {
        return;
    }

    if (x < p->value)
    {
        _remove(x, p->left);
    }
    else if (x > p->value)
    {
        _remove(x, p->right);

    }
    else
    {
        if (p->left != NULL && p->right != NULL)
        {
            //如果待删除节点有两个子节点
            //则用该节点的右子树最小节点替换待删除节点,并删除原来的最小节点
            BinaryNode<T>*pTemp = p->right;//寻找右子树最小值
            while (pTemp->left)
            {
                pTemp = pTemp->left;
            }
            p->value = pTemp->value;
            delete pTemp;
            pTemp = NULL;
        }
        else
        {
            BinaryNode<T>*pTemp = p;
            p = (p->left != NULL) ? p->left : p->right;
            delete pTemp;
        }
    }
}

template<class T>
BinaryNode<T>* BinarySearchTree<T>::_find(const T&x, BinaryNode<T>*p)
{
    if (p == NULL)
    {
        return NULL;
    }
    else if (x < p->value)
    {
        return _find(x, p->left);
    }
    else if (x > p->value)
    {
        return _find(x, p->right);
    }
    else
    {
        return p;
    }
}

template<class T>
void BinarySearchTree<T>::_printTree(BinaryNode<T>*p) const
{
    if (p != NULL)
    {
        _printTree(p->left);
        cout << p->value <<endl;
        _printTree(p->right);
    }
}

template<class T>
void BinarySearchTree<T>::_makeEmpty(BinaryNode<T>* &p)
{
    if (p->left != NULL)
    {
        _makeEmpty(p->left);
    }

    if (p->right != NULL)
    {
        _makeEmpty(p->right);
    }

    delete p;
    p = NULL;
}


int main()
{
    BinarySearchTree<int> mySeachTree;
    mySeachTree.insert(5);
    mySeachTree.insert(7);
    mySeachTree.insert(9);
    mySeachTree.insert(0);
    mySeachTree.insert(45);
    mySeachTree.insert(33);
    mySeachTree.insert(1);

    mySeachTree.printTree();

    cout << "min " << mySeachTree.findMin()->value << endl;
    cout << "max " << mySeachTree.findMax()->value << endl;
    mySeachTree.remove(33);
    mySeachTree.printTree();


    mySeachTree.makeEmpty();
    system("pause");
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值