二叉搜索树完整实现(BST)

几段重要的代码以及讲解

一.findMin和findMax

    Node* findMin(Node* t) const
    {
        if (t == nullptr)  return nullptr;
        if (t->left == nullptr) return t;
        return findMin(t->left);
    }

    Node* findMax(Node* t) const
    {
        if (t == nullptr)  return nullptr;
        if (t->right == nullptr) return t;
        return findMax(t->right);
    }

二.insert

   /*
    void insert(E x, Node* t)
    {
        if (t == nullptr)
            t = new Node{ x,nullptr,nullptr };
        else if (x < t->data) insert(x, t->left);
        else if (x > t->data)    insert(x, t->right);
        else;
    }
    */


    void insert(const E &x, Node* &t)
    {
        if (t == nullptr)
            t = new Node{ x,nullptr,nullptr };
        else if (x < t->data)    insert(x, t->left);
        else if (x > t->data)    insert(x, t->right);
        else;
    }
    
    
    void insert(E&& x,Node*& t)
    {
        if (t == nullptr)
            t = new Node{ std::move(x),nullptr,nullptr };
        else if (x < t->data)
            insert(std::move(x), t->left);
        else if (x > t->data)
            insert(std::move(x), t->right);
        else;
    }

三.remove

//这里一定要用Node *&
    void remove(const E& x, Node*& t)
    {
        if (t == nullptr) return;
        if (x < t->data)      remove(x, t->left);
        else if (x > t->data) remove(x, t->right);
        else if (t->left != nullptr && t->right != nullptr)  //两个儿子
        {
            t->data = findMin(t->right)->data;      //用右子树的最小值来代替这个要被删除的结点的值
            remove(t->data, t->right);              //递归的删除用来替代的结点
        }
        else
        {
            Node* old = t;
            t = (t->left != nullptr) ? t->left : t->right;
            delete old;
        }
    }

  /*
    void remove(E x, Node* t)
    {
        if (t == nullptr) return;
        if (x < t->data) remove(x, t->left);
        else if (x > t->data) remove(x, t->right);
        else if (t->left != nullptr && t->right != nullptr)  //两个儿子
        {
            t->data = findMin(t->right)->data;      //用右子树的最小值来代替这个要被删除的结点的值
            remove(t->data, t->right);              //递归的删除用来替代的结点
        }
        else
        {
            Node* old = t;
            t = (t->left != nullptr) : t->left ? t->right;
            delete old;
        }
    }*/

四.树的遍历(前中后序)

    
    void printTree_Inorder(Node* t) const
    {
        if (t != nullptr)
        {
            printTree_Inorder(t->left);
            std::cout << t->data << " ";
            printTree_Inorder(t->right);
        }
        
    }

    void printTree_Preorder(Node* t) const 
    {
        if (t != nullptr)
        {
            std::cout << t->data << " ";
            printTree_Preorder(t->left);
            printTree_Preorder(t->right);
        }
    }

    void printTree_Postorder(Node* t) const
    {
        if (t != nullptr)
        {
            printTree_Postorder(t->left);
            printTree_Postorder(t->right);
            std::cout << t->data<< " ";
        }
    }

思想说明

充分利用C++类的特性,所有的public函数只提供接口(即调用private函数),所有的private函数进行实现。

全部实现代码(BinarySearchTree.cpp)

#include<iostream>

/*
   public 函数基本只提供接口,所有的实现都在 private 函数里实现
*/
template<typename E>
class BinarySearchTree
{
private:
    struct Node
    {
        E data;
        Node* left;
        Node* right;
        Node(const E& element, Node* lt, Node* rt)
            :data{ element }, left{ lt }, right{ rt }
        {

        }
    };

    Node* root;

    Node* clone(Node* t) const
    {
        if (t == nullptr)  return nullptr;
        else return new Node{ t->data,clone(t->left),clone(t->right) };
    }

    void makeEmpty(Node*& t)
    {
        if (t != nullptr)
        {
            makeEmpty(t->left);
            makeEmpty(t->right);
            delete t;
        }
        t = nullptr;
    }

    //这里使用常量引用类型 const E& 避免对x进行修改,同时程序更加高效
    //函数为const 避免修改成员函数
    bool find(const E& x, Node* t) const
    {
        /* x=10 */
        if (t == nullptr)      return false;
        else if (x < t->data)  return find(x, t->left);
        else if (x > t->data)  return find(x, t->right);
        else                   return true;
    }

    Node* findMin(Node* t) const
    {
        if (t == nullptr)  return nullptr;
        if (t->left == nullptr) return t;
        return findMin(t->left);
    }

    Node* findMax(Node* t) const
    {
        if (t == nullptr)  return nullptr;
        if (t->right == nullptr) return t;
        return findMax(t->right);
    }

    /*
    void insert(E x, Node* t)
    {
        if (t == nullptr)
            t = new Node{ x,nullptr,nullptr };
        else if (x < t->data) insert(x, t->left);
        else if (x > t->data)    insert(x, t->right);
        else;
    }*/


    void insert(const E &x, Node* &t)
    {
        if (t == nullptr)
            t = new Node{ x,nullptr,nullptr };
        else if (x < t->data)    insert(x, t->left);
        else if (x > t->data)    insert(x, t->right);
        else;
    }
    
    
    void insert(E&& x,Node*& t)
    {
        if (t == nullptr)
            t = new Node{ std::move(x),nullptr,nullptr };
        else if (x < t->data)
            insert(std::move(x), t->left);
        else if (x > t->data)
            insert(std::move(x), t->right);
        else;
    }

    //这里一定要用Node *&
    void remove(const E& x, Node*& t)
    {
        if (t == nullptr) return;
        if (x < t->data)      remove(x, t->left);
        else if (x > t->data) remove(x, t->right);
        else if (t->left != nullptr && t->right != nullptr)  //两个儿子
        {
            t->data = findMin(t->right)->data;      //用右子树的最小值来代替这个要被删除的结点的值
            remove(t->data, t->right);              //递归的删除用来替代的结点
        }
        else
        {
            Node* old = t;
            t = (t->left != nullptr) ? t->left : t->right;
            delete old;
        }
    }

    /*
    void remove(E x, Node* t)
    {
        if (t == nullptr) return;
        if (x < t->data) remove(x, t->left);
        else if (x > t->data) remove(x, t->right);
        else if (t->left != nullptr && t->right != nullptr)  //两个儿子
        {
            t->data = findMin(t->right)->data;      //用右子树的最小值来代替这个要被删除的结点的值
            remove(t->data, t->right);              //递归的删除用来替代的结点
        }
        else
        {
            Node* old = t;
            t = (t->left != nullptr) : t->left ? t->right;
            delete old;
        }
    }*/

    void printTree_Inorder(Node* t) const
    {
        if (t != nullptr)
        {
            printTree_Inorder(t->left);
            std::cout << t->data << " ";
            printTree_Inorder(t->right);
        }
        
    }
    void printTree_Preorder(Node* t) const 
    {
        if (t != nullptr)
        {
            std::cout << t->data << " ";
            printTree_Preorder(t->left);
            printTree_Preorder(t->right);
        }
    }
    void printTree_Postorder(Node* t) const
    {
        if (t != nullptr)
        {
            printTree_Postorder(t->left);
            printTree_Postorder(t->right);
            std::cout << t->data<< " ";
        }
    }
public:
    BinarySearchTree()
        :root{nullptr}
    {

    }
    BinarySearchTree(const BinarySearchTree & rhs)
        :root{nullptr}
    {
       root= clone(rhs.root);
    }
    ~BinarySearchTree()
    {
        makeEmpty(root);
    }
     
    E findMinNode() const
    {
        return findMin(root)->data;
    }

    E findMaxNode() const
    {
        return findMax(root)->data;
    }

    void insert(const E& data)
    {
        insert(data, root);
    }
    void remove(const E& data)
    {
        remove(data, root);
    }

    bool find(const E& x)
    {
        return find(x, root);
    }
    bool isEmpty() const
    {
        return root == nullptr?true : false;
    }

    void print(std::string order) const
    {
        
        if (order == "in")   printTree_Inorder(root);
        else if (order == "pre")  printTree_Preorder(root);
        else if (order == "post") printTree_Postorder(root);
    }

};

测试函数(main.cpp)

代码



#include <iostream>
#include "BinarySearchTree.cpp"
int main()
{
    BinarySearchTree<int> BST_test;


    BST_test.insert(9);
    BST_test.insert(4);
    BST_test.insert(15);
    BST_test.insert(26);
    BST_test.insert(11);
    BST_test.insert(16);
    BST_test.insert(5);
    BST_test.insert(7);
    BST_test.insert(10);
    BST_test.insert(14);
    BST_test.insert(19);
    BST_test.print("post");
    std::cout << std::endl;
    BST_test.print("in");
    std::cout << std::endl;
    BST_test.print("pre");
    system("pause");

    BST_test.remove(15);
    BST_test.print("post");
    std::cout << std::endl;
    BST_test.print("in");
    std::cout << std::endl;
    BST_test.print("pre");
    system("pause");

    std::cout << BST_test.findMinNode() << std::endl;
    std::cout << BST_test.findMaxNode() << std::endl;

    std::cout << BST_test.isEmpty();

}

运行结果

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值