查找二叉树(二)

查找二叉树模板类的完全实现

查找二叉树的特点是:左子树的所有节点小于根节点,右子树的所有节点大于根节点。
类似的数据结构最难的操作是remove操作,这也是本文中最经典的操作(自我感觉),在代码后面详细说一下remove操作

binaryTree.h
#ifndef BINARYSEARCHTREE_H
#define BINARYSEARCHTREE_H

template<typename Comparable>
class BinarySearchTree
{
public:
    BinarySearchTree();
    BinarySearchTree(const BinarySearchTree& rhs);
    ~BinarySearchTree();

    const Comparable& findMin() const;
    const Comparable& findMax() const;
    bool contains(const Comparable& x) const;
    bool isEmpty() const;
    void printTree() const;

    void makeEmpty();
    void insert(const Comparable& x);
    void remove(const Comparable& x);

    const BinarySearchTree& operator=(const BinarySearchTree& rhs);

private:
    struct BinaryNode
    {
        Comparable element;
        BinaryNode* left;
        BinaryNode* right;

        BinaryNode(const Comparable& theElement, BinaryNode* lt, BinaryNode* rt) :
            element(theElement), left(lt), right(rt){}
    };

    BinaryNode* root;

private:
    void insert(const Comparable &x, BinaryNode*& t) const;
    void remove(const Comparable &x, BinaryNode*& t) const;
    BinaryNode* findMin(BinaryNode* t) const;
    BinaryNode* findMax(BinaryNode* t) const;
    bool contains(const Comparable &x, BinaryNode* t) const;
    void makeEmpty(BinaryNode*& t);
    void printTree(BinaryNode* t) const;
    BinaryNode* clone(BinaryNode *t) const;

};

#endif // BINARYSEARCHTREE_H
binaryTree.cpp
#include "binarySearchTree.h"

#include <iostream>

template<typename Comparable>
BinarySearchTree<Comparable>::BinarySearchTree()
{
    root = nullptr;
}

template<typename Comparable>
BinarySearchTree<Comparable>::BinarySearchTree(const BinarySearchTree &rhs)
{
    this->root = clone(rhs.root);
}

template<typename Comparable>
BinarySearchTree<Comparable>::~BinarySearchTree()
{
    makeEmpty();
}

template<typename Comparable>
const Comparable &BinarySearchTree<Comparable>::findMin() const
{
    return findMin(root);
}

template<typename Comparable>
const Comparable &BinarySearchTree<Comparable>::findMax() const
{
    return findMax(root);
}

template<typename Comparable>
bool BinarySearchTree<Comparable>::contains(const Comparable &x) const
{
    return contains(x, root);
}

template<typename Comparable>
bool BinarySearchTree<Comparable>::isEmpty() const
{
    if(root == nullptr)
        return true;
    else
        return false;
}

template<typename Comparable>
void BinarySearchTree<Comparable>::printTree() const
{
    printTree(root);
}

template<typename Comparable>
void BinarySearchTree<Comparable>::makeEmpty()
{
    makeEmpty();
}

template<typename Comparable>
void BinarySearchTree<Comparable>::insert(const Comparable &x)
{
    insert(x, root);
}

template<typename Comparable>
void BinarySearchTree<Comparable>::remove(const Comparable &x)
{
    remove(x, root);
}

template<typename Comparable>
const BinarySearchTree<Comparable> &BinarySearchTree<Comparable>::operator=(const BinarySearchTree &rhs)
{
    if(this != &rhs)
    {
        makeEmpty();
        root = clone(rhs.root);
    }
    return *this;
}

///
/// down private:
///

template<typename Comparable>
void BinarySearchTree<Comparable>::insert(const Comparable &x, BinarySearchTree<Comparable>::BinaryNode *&t) const
{
    if(t == nullptr)
        t = new BinaryNode(x, nullptr, nullptr);
    else if(x < t->element)
        insert(x, t->left);
    else if(t->element < x)
        insert(x, t->right);
    else
        ;
}

template<typename Comparable>
void BinarySearchTree<Comparable>::remove(const Comparable &x, BinarySearchTree<Comparable>::BinaryNode *&t) const
{
    if(t == nullptr)
        return;
    if(x < t->element)
        remove(x, t->left);
    else if(t->element < x)
        remove(x, t->right);
    else if(t->left != nullptr && t->right != nullptr)
    {
        t->element = findMin(t->right)->element;
        remove(t->element, t->right);
    }
    else
    {
        BinaryNode *oldNode = t;
        t = (t->left != nullptr)?t->left:t->right;
        delete oldNode;
    }
}

template<typename Comparable>
typename BinarySearchTree<Comparable>::BinaryNode *BinarySearchTree<Comparable>::findMin(BinarySearchTree<Comparable>::BinaryNode *t) const
{
    if(t == nullptr)
        return nullptr;
    if(t->left == nullptr)
        return t;
    return findMin(t->left);
}

template<typename Comparable>
typename BinarySearchTree<Comparable>::BinaryNode *BinarySearchTree<Comparable>::findMax(BinarySearchTree<Comparable>::BinaryNode *t) const
{
    if(t != nullptr)
        while(t->right != nullptr)
            t = t->right;
    return t;
}

template<typename Comparable>
bool BinarySearchTree<Comparable>::contains(const Comparable &x, BinarySearchTree<Comparable>::BinaryNode *t) const
{
    if(t == nullptr)
        return false;
    else if(x < t->element)
        return contains(x, t->left);
    else if(t->element < x)
        return contains(x, t->right);
    else
        return true;
}

template<typename Comparable>
void BinarySearchTree<Comparable>::makeEmpty(BinarySearchTree<Comparable>::BinaryNode *&t)
{
    if(t != nullptr)
    {
        makeEmpty(t->left);
        makeEmpty(t->right);
        delete t;
    }
    t = nullptr;
}

template<typename Comparable>
void BinarySearchTree<Comparable>::printTree(BinarySearchTree<Comparable>::BinaryNode *t) const
{
    if(t != nullptr)
    {
        std::cout << t->element << " ";
        printTree(t->left);
        printTree(t->right);
    }
}

template<typename Comparable>
typename BinarySearchTree<Comparable>::BinaryNode *BinarySearchTree<Comparable>::clone(BinarySearchTree<Comparable>::BinaryNode *t) const
{
    if(t == nullptr)
        return nullptr;
    return new BinaryNode(t->element, clone(t->left), clone(t->right));
}

查找二叉树的remove操作需要在删除节点后,其余的树还符合查找二叉树的特征。这也就造成了remove的难点,不能简单的delete。

remove分为三种情况
要删除的节点是叶子节点:

这种情况是最简单的,直接delete Node

要删除的节点有一个子节点:

直接用子节点代替要删除的节点
删除Node

要删除的节点有两个子节点:

查找要删除节点右子树中的最小节点
有这个最小节点代替要删除的节点
delete Node

之所以觉的remove经典是因为在remove中使用指针的引用,至于为什么大家可以结合代码自己体会一下。

猜你喜欢

转载自blog.csdn.net/a119258/article/details/80882214
今日推荐