美文网首页
BinaryTree

BinaryTree

作者: 世界上的一道风 | 来源:发表于2019-07-07 20:55 被阅读0次
//
// Created by ZC on 2019-07-06.
//
#include<iostream>
#include<string>
using namespace std;
template<typename treeElemType>
class BinaryTree; // 前置声明


template <typename valType>
class BTnode{
public:
    BTnode(const valType&);
    void insert_value(const valType &val);
    void remove_value(const valType&, BTnode *&);
    static void lchild_leaf(BTnode *leaf, BTnode *subtree);
    void preorder(BTnode *, std::ostream &) const;
    void display_val(BTnode *,std::ostream &);
    friend class BinaryTree<valType>;
private:
    valType _val;
    int _cnt;
    BTnode *_lchild;
    BTnode *_rchild;
};


template <typename treeElemType>
class BinaryTree{
public:
    BinaryTree();
    BinaryTree(const BinaryTree& );
    ~BinaryTree();
    BinaryTree& operator=(const BinaryTree&);
    void insert(const treeElemType&);
    bool empty() {return _root == 0;}
    void remove(const treeElemType&);
    void remove_root();
    void clear(BTnode<treeElemType> *);
    void preorder(BTnode<treeElemType>*, ostream &);
    void display_val(BTnode<treeElemType>*, ostream &);
    BTnode<treeElemType> * return_root();
private:
    BTnode<treeElemType> *_root;
    void copy(BTnode<treeElemType>*tar, BTnode<treeElemType>*src);
};

template <typename treeElemType>
inline BTnode<treeElemType> * BinaryTree<treeElemType>::return_root() {
    return _root;
}

template <typename treeElemType>
inline void BinaryTree<treeElemType>::display_val(BTnode<treeElemType>*tar, ostream &os) {
    if (tar)
        os << tar->_val<< ' ';

}

template <typename treeElemType>
void BinaryTree<treeElemType>::preorder(BTnode<treeElemType>* tar, ostream &os)
{
    if (tar)
    {
        display_val(tar, os);
        if(tar->_lchild) preorder(tar->_lchild, os);
        if(tar->_rchild) preorder(tar->_rchild, os);
    }
}
template <typename treeElemType>
inline BinaryTree<treeElemType>::
BinaryTree() : _root(0)
{}

template <typename treeElemType>
inline BinaryTree<treeElemType>::
BinaryTree(const BinaryTree &rhs)
{copy(_root, rhs._root);}

template <typename treeElemType>
inline BinaryTree<treeElemType>::
        ~BinaryTree() {clear(this->_root);}

template <typename treeElemType>
inline BinaryTree<treeElemType>&
BinaryTree<treeElemType>::
operator=(const BinaryTree &rhs)
        {
            if(this != &rhs) // 取地址
            {clear(this->_root); copy(_root, rhs._root);}
            return *this;
        }

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

template <typename valType>
inline BTnode<valType>::
BTnode(const valType &val):_val(val) //成员函数初始化,因为val可能是类类型
{
    _cnt = 1;
    _lchild = _rchild = 0;
}


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);

    }

    if ( val > _val)
    {
        if(!_rchild)
            _rchild = new BTnode(val);
        else _rchild->insert_value(val);
    }
}


template <typename valType>
void BTnode<valType>::
lchild_leaf(BTnode *leaf, BTnode *subtree) { //一直搜索到最左边叶节点
    while( subtree -> _lchild)
        subtree = subtree -> _lchild;
    subtree->_lchild = leaf;
}

// *& prev: reference to pointer
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 treeElemType>
inline void BinaryTree<treeElemType>::
remove(const treeElemType &elem) {
    if (_root)
    {
        if (_root->_val == elem)
            remove_root();
        else
            _root->remove_value(elem, _root);
    }
}

template<typename treeElemType>
inline void BinaryTree<treeElemType>::
remove_root() {
    if(!_root) return;

    BTnode<treeElemType> *tmp = _root;
    if(_root->_rchild)
    {
        _root = _root->_rchild;
        //搬动左子节点到右子节点的左子树底部
        if(tmp->_lchild)
        {
            BTnode<treeElemType> *lc = tmp->_lchild;
            BTnode<treeElemType> *newlc = _root->_lchild;
            if (!newlc)
                //没有任何子树
                _root->_lchild = lc;
            else BTnode<treeElemType>::lchild_leaf(lc, newlc);
        }

    }
    else _root = _root->_lchild;

    delete tmp;
}

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


template  <typename  valType>
void BTnode<valType>::
preorder(BTnode *pt, 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>::display_val(BTnode *pt, std::ostream &os) {
    if (pt)
        os << pt->_val;
}

test:



int main(){
    BinaryTree<string> bt;
    bt.insert("Piglet");
    bt.insert("Eeyore");
    bt.insert("Roo");
    bt.insert("Tigger");
    bt.insert("Chris");
    bt.insert("Pooh");
    bt.insert("Kanga");

    cout << "Preorder travelsal : \n";
    bt.preorder(bt.return_root(), cout);

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

    bt.remove("Eeyore");
    cout << "\nPreorder traversal after Eeyore removal: \n";
    bt.preorder(bt.return_root(), cout);
    return 0;
}


Preorder travelsal : 
Piglet Eeyore Chris Kanga Roo Pooh Tigger 
Preorder traversal after Piglet removal: 
Roo Pooh Eeyore Chris Kanga Tigger 
Preorder traversal after Eeyore removal: 
Roo Pooh Kanga Chris Tigger 
Process finished with exit code 0

相关文章

网友评论

      本文标题:BinaryTree

      本文链接:https://www.haomeiwen.com/subject/tlbihctx.html