二叉搜索树

来源:互联网 发布:疯狂淘宝李涛是真是假 编辑:程序博客网 时间:2024/06/18 04:33

二叉搜索树
【概念】
二叉搜索树:又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树
1、若它的左子树不为空,则左子树上所有节点的值都小于根节点的值
2、若它的右子树不为空,则右子树上所有节点的值都大于根节点的值
3、它的左右子树也分别为二叉搜索树
例:此树就是一颗二叉搜索树。
这里写图片描述
【操作】

—搜索:若根节点不为空
如果根节点的key==查找key,返回true
如果根节点的key<查找key,在其左子树中查找
如果根节点的key>查找key,在其右子树中查找
否则,返回false

—插入:
在向二叉搜索树中插入新元素时,必须先检测这个元素是否在树中已经存在。如果搜索成功,说明该元素已经存在,则不进行插入;否则将新元素加入到搜索停止的地方。

—删除:
首先查找元素是否在二叉搜索树中,如果不存在,则返回;否则要删除的结点可能分下面四种情况:

1、要删除的结点无孩子结点;
2、要删除的结点只有左孩子结点;
3、要删除的结点只有右孩子结点;
4、要删除的结点有左、右孩子结点;

对于上述情况,相应的删除方法如下:
a、直接删除该结点
b、删除该结点且使被删除节点的双亲结点指向被删除节点的左孩子点;
c、删除该结点且使被删除节点的双亲结点指向被删除结点的右孩子点;
d、在它的右子树中寻找中序下的第一个结点(关键码最小),用它的值补 到被删除节点中,在来处理该结点的删除问题

1–>a :这里写图片描述
2–b :这里写图片描述
3–c :这里写图片描述
4–d :这里写图片描述

源代码:

template<class T>struct BinarySearchTreeNode{    BinarySearchTreeNode<T>*_pleft;    BinarySearchTreeNode<T>*_pright;    T _key;    BinarySearchTreeNode(const T&key)        :_pleft(NULL)        , _pright(NULL)        , _key(key)    {}};template<class T>class BinarySearchTree{    typedef BinarySearchTreeNode<T> Node;public:    BinarySearchTree()        :_proot(NULL)    {}    BinarySearchTree(T*a, size_t size)    {        _proot = NULL;        for (int i = 0; i < size; ++i)        {            Insert(a[i]);        }    }    bool Insert(const T&data)    {        if (_proot == NULL)        {            _proot = new Node(data);            return true;        }        Node*pCur = _proot;        Node*parent = NULL;        while (pCur)        {            parent = pCur;            if (pCur->_key < data)                pCur = pCur->_pright;            else if (pCur->_key>data)                pCur = pCur->_pleft;            else                return false;        }        if (parent->_key < data)            parent->_pright = new Node(data);        else if(parent->_key > data)            parent->_pleft = new Node(data);        return true;    }    Node* Find(const T&data)    {        Node*pCur = _proot;        while (pCur)        {            if (data == pCur->_key)                return pCur;            if (data < pCur->_key)                pCur = pCur->_pleft;            else                pCur = pCur->_pright;        }        return NULL;    }    bool Remove(const T&data)    {        Node*pCur = _proot;        Node*parent = NULL;        while (pCur)        {            if (pCur->_key < data)            {                parent = pCur;                pCur = pCur->_pright;            }            else if (pCur->_key>data)            {                parent = pCur;                pCur = pCur->_pleft;            }            else            {                if (pCur->_pleft == NULL)//当前节点左孩子为空,将右孩子直接复制                {                    if (parent == NULL)//判断当前节点是不是根节点                    {                        _proot = pCur->_pright;                    }                    else//待删除结点为右孩子                    {                        if (parent->_pleft == pCur)                            parent->_pleft = pCur->_pright;                        else                            parent->_pright = pCur->_pright;                    }                    delete pCur;                }                else if (parent->_pright == NULL)//待删除结点为左孩子                {                    if (parent == NULL)                    {                        _proot = pCur->_pright;                    }                    else                    {                        if (parent->_pleft == pCur)                            parent->_pleft = pCur->_pleft;                        else                            parent->_pright = pCur->_pleft;                    }                    delete pCur;                }                else//左右子树都不为空,将右子树中最左节点交换                {                    Node*tmp = pCur->_pright;                    Node*prev = pCur;                    while (tmp->_pleft)                    {                        prev = tmp;                        tmp = tmp->_pleft;                    }                    swap(tmp->_key, pCur->_key);                    if (tmp==prev->_pright)                    {                        pCur->_pright = tmp->_pright;                    }                    else if (prev->_pleft==tmp)                    {                        prev->_pleft = tmp->_pright;                    }                    delete tmp;                }                return true;            }        }        return false;    }    BinarySearchTree<T>& operator=(BinarySearchTree<T>&tree)    {        if (this != &tree)        {            BinarySearchTree<T>tmp(tree);            swap(_proot, tmp._proot);        }        return *this;    }    BinarySearchTree(const BinarySearchTree<T>&tree)        :_proot(NULL)    {        if (tree._proot == NULL)            return;        queue<Node*>q;        q.push(tree._proot);        while (!q.empty())        {            Node*pCur = q.front();            Insert(pCur->_key);            q.pop();            if (pCur->_pleft)            {                q.push(pCur->_pleft);            }            if (pCur->_pright)            {                q.push(pCur->_pright);            }        }    }    ~BinarySearchTree()    {        _Destory(_proot);    }    Node*_Find_Min(const Node&proot)    {        assert(proot);        while (proot->_pleft)        {               proot = proot->_pleft;        }        return proot;    }    Node*_Find_MAX(const Node&proot)    {        assert(proot);        while (proot->_pright)        {            proot = proot->_pright;        }        return proot;    }private:    void _Destory(Node*proot)    {        if (proot == NULL)            return;        _Destory(proot->_pleft);        _Destory(proot->_pright);        delete proot;    }private:    BinarySearchTreeNode<T>*_proot;};
0 0
原创粉丝点击