C++实现二叉搜索树的基本功能

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/NichChen/article/details/84193412

文中包括BST的:初始化、析构、插入、删除(重点部分)、清空、查找、先序遍历、中序遍历、后序遍历

代码:

bst.h

#ifndef BST_H
#define BST_H

#include <iostream>

template<typename T = int>
class BinaryTree
{
public:
    BinaryTree() = default;
    BinaryTree(const BinaryTree &bt);
    BinaryTree(const T &theElement);

    ~BinaryTree();

    void insert(const T &theElement);
    void remove(const T &theElement);
    void makeEmpty();
    bool isFind(const T &theElement) const;
    void preOrder() const;
    void inOrder() const;
    void postOrder() const;

private:
    struct BinaryNode
    {
        T element;
        BinaryNode* leftNode;
        BinaryNode* rightNode;
        BinaryNode(const T &ele, BinaryNode* left, BinaryNode* right)
            : element(ele), leftNode(left), rightNode(right) {}
        BinaryNode(const T &ele): element(ele), leftNode(nullptr), rightNode(nullptr){}
        BinaryNode(const BinaryNode* bNode)
            : element(bNode->element), leftNode(bNode->leftNode), rightNode(bNode->rightNode){}
    };

    BinaryNode* root;
    BinaryNode* clone(const BinaryNode* bNode);
    void insert(const T& theElement, BinaryNode* &t);
    void remove(const T& theElement, BinaryNode* &t);
    void makeEmpty(BinaryNode* &t);
    bool isFind(const T &theElement, BinaryNode* t) const;
    BinaryNode* findMin(BinaryNode* bNode) const;
    BinaryNode* findMax(BinaryNode* bNode) const;
    void preOrder(BinaryNode* bNode) const;
    void inOrder(BinaryNode* bNode) const;
    void postOrder(BinaryNode* bNode) const;
};


#endif // BST_H

bst.cpp

#include <iostream>
#include "bst.h"

template<typename T>
BinaryTree<T>::BinaryTree(const BinaryTree &bt)
{
    if(nullptr != bt.root) {
        this->root = clone(bt.root);
    } else {
        root = nullptr;
    }
}

template<typename T>
BinaryTree<T>::BinaryTree(const T &theElement)
{
    root = new BinaryNode(theElement);
    /*
    root->element = theElement;
    root->leftNode = nullptr;
    root->rightNode = nullptr;
    */
}

template<typename T>
BinaryTree<T>::~BinaryTree()
{
    makeEmpty();
//    root->~BinaryNode();
}

template<typename T>
void BinaryTree<T>::insert(const T &theElement)
{
    insert(theElement, root);
}

template<typename T>
void BinaryTree<T>::remove(const T &theElement)
{
    remove(theElement, root);
}

template<typename T>
void BinaryTree<T>::makeEmpty()
{
    makeEmpty(root);
}

template<typename T>
bool BinaryTree<T>::isFind(const T &theElement) const
{
    isFind(theElement, root);
}

template<typename T>
void BinaryTree<T>::preOrder() const
{
    preOrder(root);
}

template<typename T>
void BinaryTree<T>::inOrder() const
{
    inOrder(root);
}

template<typename T>
void BinaryTree<T>::postOrder() const
{
    postOrder(root);
}

template<typename T>
typename BinaryTree<T>::BinaryNode* BinaryTree<T>::clone(const BinaryNode* r)
{
    //这个时候typename的作用就是告诉c++编译器,typename后面的字符串为一个类型名称,而不是成员函数或者成员变量
    if (nullptr == r)
    {
        return nullptr;
    }
    else
    {
        return new BinaryNode(r->element, clone(r->leftNode), clone(r->rightNode));
    }
}

template<typename T>
void BinaryTree<T>::insert(const T &theElement, BinaryNode* &t)
//指针加索引作为形参,保证运行完函数后保存对指针变量的改变操作
{
    if (nullptr == t)
    {
        t = new BinaryNode(theElement);
    }
    else if (theElement < t->element)
    {
        insert(theElement, t->leftNode);
    }
    else if (theElement > t->element)
    {
        insert(theElement, t->rightNode);
    }
    else
    {
        //重复的数据不添加到树中
    }
}


/******重点******/
template<typename T>
void BinaryTree<T>::remove(const T &theElement, BinaryNode* &t)
{
    if (nullptr == t)
    {
        return;
    }
    else
    {
        if (theElement < t->element)
        {
            remove(theElement, t->leftNode);
        }
        else if (theElement > t->element)
        {
            remove(theElement, t->rightNode);
        }
        else if (nullptr != t->leftNode && nullptr != t->rightNode) //需要删除的结点有2个孩子结点
        {
            t->element = findMin(t->rightNode)->element;  //找到右子树中的最小值,并赋值给当前待删除结点
            remove(t->element, t->rightNode);  //删除右子树中的最小点(此时待删除结点一定无左子树)
        }
        else  //需要删除的结点有1或0个孩子结点
        {
            BinaryNode* oldNode = t;
            //这里改变t,就能让t的父结点重新指向t改变后的结点处吗?(引用的作用?)
            t = (nullptr != t->leftNode) ? t->leftNode : t->rightNode;
            delete oldNode;
        }
    }
}

template<typename T>
void BinaryTree<T>::makeEmpty(BinaryNode* &t)
{
    if (nullptr != t)
    {
        makeEmpty(t->leftNode);
        makeEmpty(t->rightNode);
        std::cout << "delete: " << t->element << std::endl;
        delete t;
        t = nullptr;
    }
//    t = nullptr
}

template<typename T>
bool BinaryTree<T>::isFind(const T &theElement, BinaryNode *t) const
{
    if (nullptr == t)
    {
        return false;
    }
    else if (theElement < t->element)
    {
        return isFind(theElement, t->leftNode);
    }
    else if (theElement > t->element)
    {
        return isFind(theElement, t->rightNode);
    }
    else
    {
        //匹配
        return true;
    }
}

template<typename T>
typename BinaryTree<T>::BinaryNode* BinaryTree<T>::findMin(BinaryNode* bNode) const
{
    if (nullptr != bNode)
    {
        while (nullptr != bNode->leftNode)
        {
            bNode = bNode->leftNode;
        }
        return bNode;
    }
}

template<typename T>
typename BinaryTree<T>::BinaryNode* BinaryTree<T>::findMax(BinaryNode* bNode) const
{
    if (nullptr != bNode)
    {
        while (nullptr != bNode->rightNode)
        {
            bNode = bNode->rightNode;
        }
        return bNode;
    }
}

template<typename T>
void BinaryTree<T>::preOrder(BinaryNode* bNode) const
{
    if (nullptr != bNode)
    {
        std::cout << bNode->element << " ";
        preOrder(bNode->leftNode);
        preOrder(bNode->rightNode);
    }
}

template<typename T>
void BinaryTree<T>::inOrder(BinaryNode* bNode) const
{
    if (nullptr != bNode)
    {
        inOrder(bNode->leftNode);
        std::cout << bNode->element << " ";
        inOrder(bNode->rightNode);
    }
}

template<typename T>
void BinaryTree<T>::postOrder(BinaryNode* bNode) const
{
    if (nullptr != bNode)
    {
        postOrder(bNode->leftNode);
        postOrder(bNode->rightNode);
        std::cout << bNode->element << " ";
    }
}


main.cpp

#include <iostream>
#include "bst.h"
#include "bst.cpp"
using namespace std;

int main()
{
    int root = 5;
    int a = 3, b = 4, c = 2, d = 1, e = 8, f = 6;

    BinaryTree<int> bTree(root);
    bTree.insert(a);
    bTree.insert(b);
    bTree.insert(c);
    bTree.insert(d);
    bTree.insert(e);
    bTree.insert(f);

    cout << "bTree.isFind(7) = " << bTree.isFind(7) << endl;
    cout << "bTree.isFind(8) = " << bTree.isFind(8) << endl;

//    bTree.

    cout << "preOrder:" << endl;
    bTree.preOrder();
    cout << endl;

    cout << "inOrder:" << endl;
    bTree.inOrder();
    cout << endl;

    cout << "postOrder:" << endl;
    bTree.postOrder();
    cout << endl;

    bTree.remove(3);
    cout << "after bTree.remove(3), inOrder:" << endl;
    bTree.inOrder();
    cout << endl;

    //bTree.makeEmpty()包含在析构函数中,以后序遍历的方式删除结点


    return 0;
}

程序运行结果如下:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/NichChen/article/details/84193412
今日推荐