美文网首页
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