二叉排序树类

二叉排序树

代码

#include <iostream>

using namespace std;

// 节点类
template <typename T>
struct Node
{
    T data;
    Node<T> *left;
    Node<T> *right;
    Node<T> *parent;
    Node() : left(nullptr), right(nullptr), parent(nullptr) {}
    Node(const T &value) : data(value), left(nullptr), right(nullptr), parent(nullptr) {}
};

// 节点类工厂函数
template <typename T>
Node<T>* create_node(const T &data)
{
    Node<T> *pNode = new Node<T>(data);
    return pNode;
}

// 二叉树类
template <typename T>
class BinarySortTree
{
private:
    Node<T> *m_pRoot;

public:
    BinarySortTree()
        : m_pRoot(nullptr) {}

    ~BinarySortTree()
    {
        destroy(m_pRoot);
    }

    bool isEmpty() const
    {
        return (m_pRoot == nullptr);
    }
    
    // 利用循环进行数据插入
    void insert(const T &data)
    {
        Node<T> *pNode = create_node(data);
        if (m_pRoot == nullptr)
        {
            m_pRoot = pNode;
        }
        else
        {
            Node<T> *pCur = m_pRoot;
            Node<T> *pPre = nullptr;
            while (pCur != nullptr)
            {
                pPre = pCur;
                if (data < pCur->data)
                {
                    pCur = pCur->left;
                }
                else if (data > pCur->data)
                {
                    pCur = pCur->right;
                }
                else
                {
                    delete pNode;
                    return;
                }
            }
            if (data < pPre->data)
            {
                pPre->left = pNode;
            }
            else
            {
                pPre->right = pNode;
            }
            pNode->parent = pPre;
        }
    }

    // 利用递归进行数据插入
    void insertByRecur(const T &data)
    {
        if (m_pRoot == nullptr)
        {
            Node<T> *pNode = create_node(data);
            m_pRoot = pNode;
        }
        else
        {
            // 调用private递归插入函数
            insert(m_pRoot, data);
        }
    }

    // 查找数据为data的节点,如果不存在则返回空指针
    Node<T>* find(const T &data)
    {
        Node<T> *pCur = m_pRoot;
        while (pCur != nullptr)
        {
            if (data < pCur->data)
            {
                pCur = pCur->left;
            }
            else if (data > pCur->data)
            {
                pCur = pCur->right;
            }
            else
            {
                break;
            }
        }
        return pCur;
    }

    // 删除值为data的节点所在的子树
    void deleteSubTree(const T &data)
    {
        Node<T> *pNode = find(data);
        if (pNode != nullptr)
        {
            // 调用private成员函数
            deleteSubTree(pNode);
        }
    }

    // 删除值为data的节点
    void deleteNode(const T &data)
    {
        Node<T> *pNode = find(data);
        if (pNode != nullptr)
        {
            // 调用private成员函数
            deleteNodeImpl(pNode);
        }      
    }

    void print() const
    {
        // 调用private成员函数
        print(m_pRoot);
        cout << endl;
    }

private:
    // 销毁二叉排序树
    static void destroy(Node<T> *pRoot)
    {
        if (pRoot == nullptr)
            return;
        destroy(pRoot->left);
        destroy(pRoot->right);
        delete pRoot;
        pRoot = nullptr;        
    }

    // 递归插入
    static void insert(Node<T> *pRoot, const T &data)
    {
        if (data < pRoot->data)
        {
            if (pRoot->left == nullptr)
            {
                Node<T> *pNode = create_node(data);
                pRoot->left = pNode;
                pNode->parent = pRoot;
            }
            else
            {
                insert(pRoot->left, data);
            }
        }
        else if (data > pRoot->data)
        {
            if (pRoot->right == nullptr)
            {
                Node<T> *pNode = create_node(data);
                pRoot->right = pNode;
                pNode->parent = pRoot;
            }
            else
            {
                insert(pRoot->right, data);
            }
        }
        else
        {
            return;
        }
    }

    // 递归删除子树
    void deleteSubTree(Node<T> *pRoot)
    {
        if (pRoot->left != nullptr)
            deleteSubTree(pRoot->left);
        if (pRoot->right != nullptr)
            deleteSubTree(pRoot->right);
        if (pRoot->parent == nullptr)
        {
            delete pRoot;
            m_pRoot = nullptr;
            return;
        }
        if (pRoot->data < pRoot->parent->data)
            pRoot->parent->left = nullptr;
        else
            pRoot->parent->right = nullptr;
        delete pRoot;        
    }

    // 分四种情况删除节点
    void deleteNodeImpl(Node<T> *pNode)
    {
        if ((pNode->left == nullptr) && (pNode->right == nullptr))
            deleteLeafNode(pNode); 
        else if ((pNode->left != nullptr) && (pNode->right == nullptr))
            deleteNodeHasLeft(pNode);
        else if ((pNode->left == nullptr) && (pNode->right != nullptr))
            deleteNodeHasRight(pNode);
        else
            deleteNodeHasBoth(pNode);
    }

    // 删除的节点为叶节点
    void deleteLeafNode(Node<T> *pNode)
    {
        if (pNode->parent == nullptr)
        {
            m_pRoot = nullptr;
        }    
        else
        {
            if (pNode->data < pNode->parent->data)
                pNode->parent->left = nullptr;
            else if (pNode->data > pNode->parent->data)
                pNode->parent->right = nullptr;
        }
        delete pNode;
    }

    // 删除的节点只有左子树
    void deleteNodeHasLeft(Node<T> *pNode)
    {
        if (pNode->parent == nullptr)
        {
            m_pRoot = pNode->left;
            m_pRoot->parent = nullptr;      
        }
        else
        {
            pNode->left->parent = pNode->parent;
            if (pNode->data < pNode->parent->data)
                pNode->parent->left = pNode->left;               
            else if (pNode->data > pNode->parent->data)
                pNode->parent->right = pNode->left;
        }
        delete pNode;
    }

    // 删除的节点只有右子树
    void deleteNodeHasRight(Node<T> *pNode)
    {
        if (pNode->parent == nullptr)
        {
            m_pRoot = pNode->right;
            m_pRoot->parent = nullptr;
            delete pNode;
        }
        else
        {
            pNode->right->parent = pNode->parent;
            if (pNode->data < pNode->parent->data)
                pNode->parent->left = pNode->right;               
            else if (pNode->data > pNode->parent->data)
                pNode->parent->right = pNode->right;
        }
        delete pNode;
    }

    // 删除的节点左右子树都存在
    void deleteNodeHasBoth(Node<T> *pNode)
    {
        Node<T> *pCur = pNode->left;
        Node<T> *pPre = nullptr;
        while (pCur != nullptr)
        {
            pPre = pCur;
            pCur = pCur->right;
        }
        T backup = pPre->data;
        deleteNodeImpl(pPre);
        pNode->data = backup;
    }

    // 中序遍历打印二叉树
    static void print(Node<T> *pRoot)
    {
        if (pRoot == nullptr)
            return;
        print(pRoot->left);
        cout << pRoot->data << " ";
        print(pRoot->right);        
    }
};

int main()
{
    BinarySortTree<int> sortTree;
    cout << "is the tree empty: " << sortTree.isEmpty() << endl;
    sortTree.insert(32);
    sortTree.insert(45);
    sortTree.insert(16);
    sortTree.insert(7);
    sortTree.insert(28);
    sortTree.insert(40);
    cout << "is the tree empty after inserting: " << sortTree.isEmpty() << endl;
    sortTree.print();
    sortTree.insertByRecur(30);
    sortTree.insertByRecur(19);
    sortTree.insertByRecur(7);
    sortTree.insertByRecur(56);
    sortTree.insertByRecur(43);
    sortTree.insertByRecur(78);
    cout << "is the tree empty after inserting: " << sortTree.isEmpty() << endl;
    sortTree.print();
    auto pNode = sortTree.find(40);
    cout << "is there 40: " << ((pNode == nullptr) ? "no" : "yes") << endl;
    pNode = sortTree.find(31);
    cout << "is there 31: " << ((pNode == nullptr) ? "no" : "yes") << endl;
    sortTree.deleteNode(28);
    cout << "after deleting 28, the tree is: " << endl;
    sortTree.print();
    sortTree.deleteNode(31);
    cout << "after deleting 31, the tree is: " << endl;
    sortTree.print();
    sortTree.deleteSubTree(45);
    cout << "after deleting subtree 45, the tree is: " << endl;
    sortTree.print();
    sortTree.deleteNode(32);
    cout << "after deleting root 35, the tree is: " << endl;
    sortTree.print();
    sortTree.deleteSubTree(16);
    cout << "after deleting subtree root 16, the tree is: " << endl;
    cout << (sortTree.isEmpty() ? "empty" : "has elem") << endl;
    return 0;
}

测试结果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值