二叉搜索树之非递归

二叉搜索树的定义:
1.每棵子树都有:左子树的值 < 根节点的值 < 右子树的值
2.中序遍历的结果是排序好的。
插入方法:
int arr[] = {5,3,4,1,7,8,2,6,0,9};
这里写图片描述
删除:
这里写图片描述
判断要删除的节点的孩子的情况:
这里写图片描述
代码:
定义节点

#pragma once
#include <iostream>
#include <windows.h>
using namespace std;
template<class K, class V>
struct BSTNode
{
    BSTNode(const K& key, const V& value)
        :_pLeft(NULL)
        ,_pRight(NULL)
        ,_key(key)
        ,_value(value)
    {}
    BSTNode<K, V>* _pLeft;
    BSTNode<K, V>* _pRight;
    K _key;
    V _value;
};

创建树

#include "BSTNode.h"
template <class K, class V>
class BSTree
{
    typedef BSTNode<K, V> Node;
public:
    BSTree()
        :_pRoot(NULL)
    {}
    BSTree(const BSTree& bst)
    {
        _pRoot = _CopyBSTree(bst._pRoot);
    }
    BSTree<K, V>& operator=(const BSTree<K, V>& bst)
    {
        if(&bst != this)
        {
            _Destroy(_pRoot);
            _pRoot = _CopyBSTree(bst._pRoot);
        }
        return *this;
    }
    bool Insert(const K& key, const V& value)
    {
        if(_pRoot == NULL)
        {
            _pRoot = new Node(key, value);
            return true;
        }
        Node* pCur = _pRoot;
        Node* pParent = NULL;
        while(pCur)
        {
            if(key < pCur->_key)
            {
                pParent = pCur;
                pCur = pCur->_pLeft;
            }
            else if(key > pCur->_key)
            {
                pParent = pCur;
                pCur = pCur->_pRight;
            }
            else
                return false;
        }
        pCur = new Node(key, value);
        if(pParent->_key > key)
            pParent->_pLeft = pCur;
        else
            pParent->_pRight = pCur;
        return true;
    }
    Node* Find(const K& key)
    {
        if(_pRoot)
        {
            Node* pCur = _pRoot;
            while(pCur)
            {
                if(pCur->_key == key)
                    return pCur;
                else if(pCur->_key > key)
                    pCur = pCur->_pLeft;
                else
                    pCur = pCur->_pRight;
            }
        }
        return NULL;
    }
    bool Remove(const K& key)
    {
        if(_pRoot == NULL)
            return false;
        if(_pRoot->_pLeft == NULL && _pRoot->_pRight == NULL && _pRoot->_key == key)
        {
            delete _pRoot;
            _pRoot = NULL;
            return true;
        }
        Node* pCur = _pRoot;
        Node* pParent = NULL;
        //先找到要删除的节点
        while(pCur)
        {
            if(pCur->_key > key)
            {
                pParent = pCur;
                pCur = pCur->_pLeft;
            }
            else if(pCur->_key < key)
            {
                pParent = pCur;
                pCur = pCur->_pRight;
            }
            else
                break;
        }
        if(pCur)
        {
            //左孩子为空,右孩子可能为空
            if(pCur->_pLeft == NULL)
            {
                //当前节点不是根节点
                if(pCur != _pRoot)
                {
                    //判断当前节点是其双亲的左孩子还是右孩子
                    if(pCur == pParent->_pLeft)
                        pParent->_pLeft = pCur->_pRight;
                    else
                        pParent->_pRight = pCur->_pRight;
                }
                else
                    _pRoot = pCur->_pRight;
            }
            //右孩子为空,左孩子不为空
            else if(pCur->_pRight == NULL)
            {
                if(pCur != _pRoot)
                {
                    if(pCur == pParent->_pLeft)
                        pParent->_pLeft = pCur->_pLeft;
                    else
                        pParent->_pRight = pCur->_pLeft;
                }
                else
                    _pRoot = pCur->_pLeft;
            }
            //左右孩子都不为空
            else
            {
                //先找到右子树的最左结点
                Node* MinNodeInRightTree = pCur->_pRight;
                pParent = pCur;
                while(MinNodeInRightTree->_pLeft)
                {
                    pParent = MinNodeInRightTree;
                    MinNodeInRightTree = MinNodeInRightTree->_pLeft;
                }
                //将最左结点与当前节点值交换
                pCur->_key = MinNodeInRightTree->_key;
                pCur->_value = MinNodeInRightTree->_value;
                //问题转化成左孩子为空
                if(MinNodeInRightTree == pParent->_pLeft)
                    pParent->_pLeft = MinNodeInRightTree->_pRight;
                else
                    pParent->_pRight = MinNodeInRightTree->_pRight;
                pCur = MinNodeInRightTree;
            }
            delete pCur;
            pCur = NULL;
            return true;
        }
        return false;
    }
    Node* GetMaxKey()
    {
        return _GetMaxKey(_pRoot);
    }
    Node* GetMinKey()
    {
        return _GetMinKey(_pRoot);
    }
    void InOrder()
    {
        cout<<"InOrder: ";
        _InOrder(_pRoot);
        cout<<endl;
    }
private:
    void _Destroy(Node*& pRoot)
    {
        if(pRoot)
        {
            _Destroy(pRoot->_pLeft);
            _Destroy(pRoot->_pRight);
            delete pRoot;
            pRoot = NULL;
        }
    }
    Node* _CopyBSTree(Node* pRoot)
    {
        Node* pCur = NULL;
        if(pRoot)
        {
            pCur = new Node(pRoot->_key, pRoot->_value);
            pCur->_pLeft = _CopyBSTree(pRoot->_pLeft);
            pCur->_pRight = _CopyBSTree(pRoot->_pRight);
        }
        return pCur;
    }
    Node* _GetMaxKey(Node* pRoot)
    {
        pRoot = pRoot->_pRight;
        while(pRoot->_pRight)
            pRoot = pRoot->_pRight;
        return pRoot;
    }
    Node* _GetMinKey(Node* pRoot)
    {
        pRoot = pRoot->_pLeft;
        while(pRoot->_pLeft)
            pRoot = pRoot->_pLeft;
        return pRoot;
    }
private:
    Node* _pRoot;
};

调用:

#include "BSTree.h"

int main()
{
    int arr[] = {5,3,4,1,7,8,2,6,0,9};
    BSTree<int, int> bt;
    for(int i=0; i<sizeof(arr)/sizeof(arr[0]); ++i)
    {
        bt.Insert_Nor(arr[i], i);
    }
    BSTree<int, int> bt1;
    bt1 = bt;
    //bt.InOrder();
    //bt.Remove_Nor(3);
    //bt.InOrder();
    //bt.Find_Nor(3);
    //bt.InOrder();
    //bt.Remove(7);
    //bt.InOrder();
    //bt.Find(1);
    //bt.GetMinKey();
    //bt.GetMaxKey();
    system("pause");
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值