二叉排序树类

二叉排序树

代码

#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;
}

测试结果

在这里插入图片描述

好的,下面是代码实现: ```cpp #include <iostream> using namespace std; // 二叉排序树结点 class BSTNode { public: int data; BSTNode *left; BSTNode *right; BSTNode(int val) { data = val; left = right = NULL; } }; // 二叉排序树 class BSTree { private: BSTNode *root; // 辅助函数:插入结点 void insertNode(int val, BSTNode *&node) { if (node == NULL) { node = new BSTNode(val); } else if (val < node->data) { insertNode(val, node->left); } else if (val > node->data) { insertNode(val, node->right); } } // 辅助函数:构造二叉排序树 void createBSTree(int arr[], int len) { for (int i = 0; i < len; i++) { insertNode(arr[i], root); } } // 辅助函数:输出查找路径 bool searchPath(int val, BSTNode *node) { if (node == NULL) { return false; } else if (val == node->data) { cout << node->data << endl; return true; } else if (val < node->data) { cout << node->data << " "; return searchPath(val, node->left); } else if (val > node->data) { cout << node->data << " "; return searchPath(val, node->right); } } // 辅助函数:判断是否二叉排序树 bool isBSTree(BSTNode *node, int min_val, int max_val) { if (node == NULL) { return true; } if (node->data < min_val || node->data > max_val) { return false; } return isBSTree(node->left, min_val, node->data - 1) && isBSTree(node->right, node->data + 1, max_val); } public: BSTree() { root = NULL; } // 插入结点 void insert(int val) { insertNode(val, root); } // 构造二叉排序树 void create(int arr[], int len) { createBSTree(arr, len); } // 输出查找路径 void search(int val) { bool found = searchPath(val, root); if (!found) { cout << "Not found!" << endl; } } // 判断是否二叉排序树 bool isBST() { return isBSTree(root, INT_MIN, INT_MAX); } }; int main() { int arr[] = { 50, 30, 70, 20, 40, 60, 80 }; int len = sizeof(arr) / sizeof(arr[0]); BSTree bst; bst.create(arr, len); int val1 = 40; bst.search(val1); int val2 = 90; bst.search(val2); bool isBST = bst.isBST(); cout << "Is a binary search tree: " << isBST << endl; return 0; } ``` 这里使用了递归实现插入结点、构造二叉排序树、输出查找路径、判断是否二叉排序树这四个成员函数。其中,构造二叉排序树函数接受一个整型数组和数组长度,通过循环调用插入结点函数来构造二叉排序树。输出查找路径函数会输出查找到的结点以及经过的路径,如果没找到则输出 "Not found!"。判断是否二叉排序树函数使用了限制最大值和最小值的方法来确保每个结点都符合二叉排序树的定义。 在主函数中,我们创建了一个整型数组并调用了 BSTree 的成员函数来操作二叉排序树,最后输出是否是二叉排序树
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值