二叉搜索树

本文用c++实现了一些二叉搜索树的基础操作以及测试代码,附带简单注释。

//二叉搜索树;
//节点结构体;
struct treeNode
{
    int iData;
    treeNode* pParent;
    treeNode* pLeft;
    treeNode* pRight;

    treeNode():
    pParent(nullptr),
    pLeft(nullptr),
    pRight(nullptr),
    iData(NULL)
    {

    }
};

//二叉搜索树;
class Tree 
{
public:
    Tree()
    {
        m_pRoot = nullptr;
        m_lCount = 0;
    }
    ~Tree()
    {

    }
private:

    //根节点指针;
    treeNode*           m_pRoot;
    //节点数量;
    long                m_lCount;
    //替换子树;
    void swapNode(treeNode* pDesNode,treeNode* pSrcNode)
    {
        if (pDesNode->pParent == nullptr)
        {
            //pDesNode是根节点,让跟节点等于新来的;
            m_pRoot = pSrcNode;
        }
        else if(pDesNode == pDesNode->pParent->pLeft)
        {
            //Des为左子节点;
            pDesNode->pParent->pLeft = pSrcNode;

        }
        else if(pDesNode == pDesNode->pParent->pRight)
        {
            //Des为右子节点;
            pDesNode->pParent->pRight = pSrcNode;
        }

        if (pSrcNode)
        {
            pSrcNode->pParent = pDesNode->pParent;
        }
    }
    //返回最小关键字元素;
    treeNode* minNode(treeNode* rootNode)
    {
        if(rootNode == nullptr) return nullptr;
        while (rootNode->pLeft)
        {
            rootNode = rootNode->pLeft;
        }

        return rootNode;
    }
    //返回最大关键字元素;
    treeNode* maxNode(treeNode* rootNode)
    {
        if(rootNode == nullptr) return nullptr;
        while (rootNode->pRight)
        {
            rootNode = rootNode->pRight;
        }

        return rootNode;
    }

public:
    //获得最小的元素值;
    const int& getMinValue()
    {
        treeNode* pTemp = minNode(m_pRoot);
        if (pTemp)
        {
            return pTemp->iData;
        }
        else
        {
            return NULL;
        }
    }
    //获得最大的元素值;
    const int& getMaxValue()
    {
        treeNode* pTemp = maxNode(m_pRoot);
        if (pTemp)
        {
            return pTemp->iData;
        }
        else
        {
            return NULL;
        }
    }
    //前驱;
    treeNode* predecessorNode(treeNode* pNode)
    {
        if (pNode->pLeft)
        {
            return maxNode(pNode->pLeft);
        }
        treeNode* pTemp = pNode->pParent;
        while (pTemp&&pTemp->pLeft == pNode)
        {
            pNode = pTemp;
            pTemp = pTemp->pParent;
        }
        return pTemp;
    }
    //后继;
    treeNode* successorNode(treeNode* pNode)
    {
        if (pNode->pRight)
        {
            return minNode(pNode->pRight);
        }
        treeNode* pTemp = pNode->pParent;
        while (pTemp&&pTemp->pRight == pNode)
        {
            pNode = pTemp;
            pTemp = pTemp->pParent;
        }
        return pTemp;
    }

    //压入数据;
    void push(int iData)
    {
        treeNode* pTemp = new treeNode;
        if (pTemp)
        {
            pTemp->iData = iData;
            insertNode(pTemp);
        }
        else
        {
            cout<<"new fail,push fail!"<<endl;
        }

    }
    //插入节点;
    void insertNode(treeNode* pNode)
    {
        if (pNode == nullptr)
        {
            return;
        }
        m_lCount++;
        //根节点为空,则插入的节点成为根节点;
        if (m_pRoot == nullptr)
        {
            m_pRoot = pNode;
            return;
        }

        treeNode* pTemp = m_pRoot;      //查找要插入的节点的位置;
        treeNode* pTempPrev = nullptr;  //要插入的子节点的父节点位置;
        while (pTemp)
        {
            pTempPrev = pTemp;

            if (pTemp->iData<pNode->iData)
            {
                //如果插入的节点数据比pTemp的数据大,则继续查找pTemp的右子树;
                pTemp = pTemp->pRight;
            }
            else
            {
                //如果插入的节点数据比pTemp的数据小或者等于,则继续查找pTemp的左子树;
                pTemp = pTemp->pLeft;
            }
        }

        if (pNode->iData<pTempPrev->iData)
        {
            //插入成为左子节点;
            pTempPrev->pLeft = pNode;
            pNode->pParent = pTempPrev;
        }
        else
        {
            //插入成为右子节点;
            pTempPrev->pRight = pNode;
            pNode->pParent = pTempPrev;
        }
    }
    //删除节点;
    void deleteNode(treeNode* pNode)
    {
        if (m_pRoot == nullptr||pNode == nullptr)
        {
            return;
        }
        m_lCount--;

        if (pNode->pLeft == nullptr)
        {
            swapNode(pNode,pNode->pRight);
            cout<<"delete success!"<<endl;
        }
        else if(pNode->pRight == nullptr)
        {
            swapNode(pNode,pNode->pLeft);
            cout<<"delete success!"<<endl;

        }
        else
        {
            //如果要删除的节点有两个子节点;
            treeNode* pTemp =minNode(pNode->pRight);
            if (pTemp!=pNode->pRight)
            {
                swapNode(pTemp, pTemp->pRight);
                pTemp->pRight = pNode->pRight;
                pTemp->pRight->pParent = pTemp;
            }
            swapNode(pNode,pTemp);
            pTemp->pLeft = pNode->pLeft;
            pTemp->pLeft->pParent = pTemp;
            cout<<"delete success!"<<endl;

        }

        delete pNode;
    }
    //查询数据;
    treeNode* search(int iData)
    {
        treeNode* pTemp = m_pRoot;
        while(pTemp!=nullptr&&iData!=pTemp->iData)
        {
            if (iData<pTemp->iData)
            {
                pTemp = pTemp->pLeft;
            }
            else
            {
                pTemp = pTemp->pRight;
            }
        }
        return pTemp;
    }
    //获得节点数量;
    const long& size()
    {
        return m_lCount;
    }
    //遍历;
    void traversal()
    {
        //中序遍历;
        if (m_pRoot == nullptr)
        {
            return;
        }

        stack<treeNode*> _stack;
        treeNode* pTemp = m_pRoot;
        while (pTemp||!_stack.empty())
        {
            if (pTemp)
            {
                _stack.push(pTemp);
                pTemp = pTemp->pLeft;
            }
            else
            {
                pTemp = _stack.top();
                cout<<pTemp->iData<<endl;
                _stack.pop();
                pTemp = pTemp->pRight;
            }
        }
    }
};


//测试二叉搜索树;
    int a[] = {70,40,90,20,50,80,100,10,30,60};
    Tree _tree;
    cout<<_tree.size()<<endl;

    for (int j = 0 ; j<10; j++)
    {
        _tree.push(a[j]);
    }
    cout<<_tree.size()<<endl;

    _tree.traversal();

    cout<<_tree.search(100)->iData<<endl;

    _tree.deleteNode(_tree.search(80));


    cout<<_tree.size()<<endl;

    _tree.traversal();

    cout<<_tree.getMinValue()  <<" " <<_tree.getMaxValue()<<endl;

    cout<<_tree.predecessorNode((_tree.search(90)))->iData<<endl;

    cout<<_tree.successorNode((_tree.search(40)))->iData<<endl;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值