C++ - 二叉树template实现

BinaryTree.h

#ifndef BINARYTREE_H
#define BINARYTREE_H

#include <iostream>

template <typename valType>
class BinaryTree;

template <typename valType>
class BTnode
{
    friend class BinaryTree<valType>;

public:
    BTnode(const valType &);
    // ~BTnode();

    // 小于根节点的所有数值都放在根节点的左子树,
    // 每个数值只能在树中出现一次。
    void insert_value(const valType &);
    // 搬移左子节点,使其成为右子节点的左子树的叶节点。
    static void lchild_leaf(BTnode *leaf, BTnode *subtree);
    // 将被删除的值val,指向目前关注的节点的父节点的指针prev。
    // 以pointer来传递,我们能够更改的是该pointer所指之物,
    // 而不是pointer本身。
    // 为了改变pointer本身,我们必须再加一层间接性。
    void remove_value(const valType &val, BTnode *&prev);
    // 先序遍历
    void preorder(BTnode *pt, std::ostream &os) const;
    // 中序遍历
    void inorder(BTnode *pt, std::ostream &os) const;
    // 后序遍历
    void postorder(BTnode *pt, std::ostream &os) const;

    void display_val(BTnode *pt, std::ostream &os) const
    {
        os << pt->_val << " ";
    }

private:
    valType _val;
    int _cnt;
    BTnode *_lchild;
    BTnode *_rchild;
};

template <typename elemType>
class BinaryTree
{
public:
    BinaryTree();
    BinaryTree(const BinaryTree &);
    ~BinaryTree();
    BinaryTree &operator=(const BinaryTree &);
    friend std::ostream &
    operator<<(std::ostream &os, const BinaryTree<elemType> &bt)
    {
        os << "Tree: " << std::endl;
        bt.print(os);
        return os;
    }

    // 判断二叉树是否为空。
    bool empty() { return _root == 0; }
    // 清空二叉树。
    void clear()
    {
        if (_root)
        {
            clear(_root);
            _root = 0;
        }
    }
    // 将新值插入二叉树中。
    void insert(const elemType &);
    // 移除某值。
    void remove(const elemType &);
    // 移除根节点。
    void remove_root();
    // 前序遍历
    void preorder() const
    {
        if (_root)
        {
            std::cout << "preorder: ";
            _root->preorder(_root, std::cout);
            std::cout << std::endl;
        }
    }

private:
    void print(std::ostream &os) const
    {
        if (_root)
        {
            _root->preorder(_root, os);
            os << std::endl;
        }
    }
    void clear(BTnode<elemType> *);
    // BTnode必须以template parameter list加以限定。
    BTnode<elemType> *_root;
    // 将src所指子树(subtree)复制到tar所指子树。
    void copy(BTnode<elemType> *tar, BTnode<elemType> *src);
};

#endif

main.cpp

#include <iostream>
#include <string>
#include "BinaryTree.h"

int main()
{
    BinaryTree<std::string> bt;

    bt.insert("Piglet");
    bt.insert("Eeyore");
    bt.insert("Roo");
    bt.insert("Tigger");
    bt.insert("Chris");
    bt.insert("Pooh");
    bt.insert("Kanga");
    std::cout << bt << std::endl;

    std::cout << "Preorder traversal: \n";
    bt.preorder();

    bt.remove("Piglet");
    std::cout << "\nPreorder traversal after Piglet removal: \n";
    bt.preorder();

    bt.remove("Eeyore");
    std::cout << "\nPreorder traversal after Eeyore removal: \n";
    bt.preorder();

    return 0;
}

template <typename elemType>
inline BinaryTree<elemType>::
    BinaryTree() : _root(0)
{
    std::cout << "BinaryTree constructor" << std::endl;
}

template <typename elemType>
inline BinaryTree<elemType>::
    BinaryTree(const BinaryTree &rhs)
{
    std::cout << "BinaryTree constructor" << std::endl;
    copy(_root, rhs._root);
}

template <typename elemType>
inline BinaryTree<elemType>::
    ~BinaryTree()
{
    std::cout << "BinaryTree destructor" << std::endl;
    clear();
}

template <typename elemType>
inline BinaryTree<elemType> &
BinaryTree<elemType>::
operator=(const BinaryTree &rhs)
{
    if (this != &rhs)
    {
        clear();
        copy(_root, rhs._root);
    }
    return *this;
}

template <typename elemType>
inline void
BinaryTree<elemType>::
    insert(const elemType &elem)
{
    if (!_root)
        _root = new BTnode<elemType>(elem);
    else
        _root->insert_value(elem);
}

template <typename elemType>
inline void
BinaryTree<elemType>::
    remove(const elemType &elem)
{
    if (_root)
    {
        if (_root->_val == elem)
            remove_root(); // 根节点的移除操作以特例处理。
        else
            _root->remove_value(elem, _root);
    }
}

template <typename elemType>
void BinaryTree<elemType>::
    remove_root()
{
    // 如果根节点不存在,直接返回。
    if (!_root)
        return;

    BTnode<elemType> *tmp = _root;
    // 如果右孩子存在。
    if (_root->_rchild)
    {
        _root = _root->_rchild;

        // 如果根节点的左孩子存在。
        if (tmp->_lchild)
        {
            // 根节点的左孩子。
            BTnode<elemType> *lc = tmp->_lchild;
            // 根节点右孩子的左孩子。
            BTnode<elemType> *rlc = _root->_lchild;

            // 如果rlc不存在,则lc为rlc。
            if (!rlc)
                _root->_lchild = lc;
            else
            {
                //  将左子树搬到右孩子的左子树底部。
                BTnode<elemType>::lchild_leaf(lc, rlc);
            }
        }
    }
    else
        _root = _root->_lchild;

    // 删除根节点。
    delete tmp;
}

template <typename elemType>
void BinaryTree<elemType>::
    clear(BTnode<elemType> *pt)
{
    if (pt)
    {
        clear(pt->_lchild);
        clear(pt->_rchild);
        delete pt;
    }
}

template <typename valType>
void BTnode<valType>::
    preorder(BTnode *pt, std::ostream &os) const
{
    if (pt)
    {
        display_val(pt, os);
        if (pt->_lchild)
            preorder(pt->_lchild, os);
        if (pt->_rchild)
            preorder(pt->_rchild, os);
    }
}

template <typename valType>
void BTnode<valType>::
    remove_value(const valType &val, BTnode *&prev)
{
    if (val < _val)
    {
        if (!_lchild)
            return; // 不在此二叉树。
        else
            _lchild->remove_value(val, _lchild);
    }
    else if (val > _val)
    {
        if (!_rchild)
            return; // 不在此二叉树。
        else
            _rchild->remove_value(val, _rchild);
    }
    else
    {
        // 重置该树,删除该节点。

        if (_rchild)
        {
            prev = _rchild;
            if (_lchild)
            {
                if (!prev->_lchild)
                    prev->_lchild = _lchild;
                else
                    BTnode<valType>::lchild_leaf(_lchild, prev->_lchild);
            }
        }
        else
            prev = _lchild;
        delete this;
    }
}

template <typename valType>
void BTnode<valType>::
    lchild_leaf(BTnode *leaf, BTnode *subtree)
{
    while (subtree->_lchild)
        subtree = subtree->_lchild;
    subtree->_lchild = leaf;
}

template <typename valType>
void BTnode<valType>::
    insert_value(const valType &val)
{
    if (val == _val)
    {
        ++_cnt;
        return;
    }

    if (val < _val)
    {
        // 到达叶子,创建新节点
        if (!_lchild)
            _lchild = new BTnode(val);
        else
            _lchild->insert_value(val);
    }
    else
    {
        if (!_rchild)
            _rchild = new BTnode(val);
        else
            _rchild->insert_value(val);
    }
}

// 将val以class类型对待,
// 使用copy constructor将val对象复制给_val。
template <typename valType>
inline BTnode<valType>::
    BTnode(const valType &val)
    : _val(val)
{
    _cnt = 1;
    _lchild = _rchild = 0;
}

输出结果

BinaryTree constructor
Tree:
Piglet Eeyore Chris Kanga Roo Pooh Tigger

Preorder traversal:
preorder: Piglet Eeyore Chris Kanga Roo Pooh Tigger

Preorder traversal after Piglet removal:
preorder: Roo Pooh Eeyore Chris Kanga Tigger

Preorder traversal after Eeyore removal:
preorder: Roo Pooh Kanga Chris Tigger
BinaryTree destructor
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值