美文网首页
二叉树实现

二叉树实现

作者: krislyy_ | 来源:发表于2018-11-27 16:39 被阅读0次

    1.层次遍历可以用于寻找叶子节点,寻找路径,寻找树的最短最大高度的非递归实现。
    2.中序遍历搜索二叉树后是升序的序列。这个特性可以判断搜索二叉树的有效性。
    3.使用双向的递归可以遍历每个分支的每个节点。

    /*
     * Created by krislyy on 2018/11/23.
     * 作为图的特殊形式,二叉树的基本组成单元是节点与边;
     * 作为数据结构,其基本的组成实体是二叉树节点,而边则
     * 对应于节点之间的相互引用
     */
    
    #pragma once
    
    #include<iostream>
    #include<queue>
    #include<stack>
    
    using namespace std;
    
    template <class T>  //树的结构体
    struct BinaryTreeNode
    {
    public:
        T _data;
        BinaryTreeNode<T>* _leftChild;
        BinaryTreeNode<T>* _rightChild;
    
    public:
        BinaryTreeNode(const T& data)
                :_data(data)
                , _leftChild(NULL)
                , _rightChild(NULL)
        {}
    
        ~BinaryTreeNode()
        {}
    };
    
    template <class T>
    class BinaryTree //树的封装
    {
    public:
        BinaryTreeNode<T>* _root;
    
    public:
        BinaryTree()
                :_root(NULL)
        {}
    
        BinaryTree( T*a, size_t size)
        {
            size_t index = 0;
            _root = _CreateBiTree(a, index, size);
        }
    
        BinaryTree(const BinaryTree& tmp)
                :_root(NULL)
        {
            _root=_Copy(tmp._root);
    
        }
        ~BinaryTree()
        {
            Destory();
        }
    
        BinaryTree<T>& operator=( BinaryTree<T> tmp)
        {
            swap(_root, tmp._root);
            return *this;
    
        }
    
        void InOrder()//中序遍历递归方法
        {
            _InOrder(_root);
            cout << endl;
        }
    
        void PreOrder()//前序遍历递归方法
        {
            _PreOrder(_root);
            cout << endl;
        }
    
        void PosOrder()//后序遍历递归方法
        {
            _PosOrder(_root);
            cout << endl;
        }
    
        void LevelOrder()//层序遍历
        {
            queue<BinaryTreeNode<T>*> s ;
            s.push(_root);
            while (!s.empty())
            {
                BinaryTreeNode<T>* cur = s.front();
                cout<<cur->_data<<' ';
                if (cur->_leftChild)
                    s.push(cur->_leftChild);
                if (cur->_rightChild)
                    s.push(cur->_rightChild);
                s.pop();
            }
            cout << endl;
        }
    
        void Size()//节点数
        {
            int size = 0;
            cout<<_Size(_root,size)<<endl;
    
        }
    
        void Hight()//深度  /高度
        {
            cout << _Hight(_root) << endl;
        }
    
        void Destory()//销毁
        {
            _Destory(_root);
            _root=NULL;
        }
    
        void LeafNum()//叶子节点数
        {
            int num = 0;
            _LeafNum(_root, num);
            cout <<num<<endl;
    
        }
    
        void PreOrderNonR()//前序 非递归  (借用栈)
        {
            if (_root == NULL)
                return;
            stack<BinaryTreeNode<T>*> s ;
            s.push(_root);
            while (!s.empty())
            {
                BinaryTreeNode<T>* cur;
                cur=s.top();
                s.pop();
                cout << cur->_data << ' ';
                if (cur->_rightChild)
                    s.push(cur->_rightChild);
                if (cur->_leftChild)
                    s.push(cur->_leftChild);
            }
            cout << endl;
        }
    
        void InOrderNonR() //中序 非递归
        {
            if (_root == NULL)
                return;
            stack<BinaryTreeNode<T>*> s;
            s.push(_root);
            BinaryTreeNode<T>* prev=NULL;
            BinaryTreeNode<T>* cur=NULL;
            while (!s.empty())
            {
                cur = s.top();
                if(prev != cur&&cur->_leftChild) //左不空 压左
                {
                    s.push(cur->_leftChild);
                }
                else //左空   出栈 输出
                {
                    cout << cur->_data << ' ';
                    s.pop();
                    if (!s.empty())
                        prev = s.top();//prev始终为出栈后的栈顶
                    if (cur->_rightChild)//  cur右不空  压右
                    {
    
                        s.push(cur->_rightChild);
    
                    }
                }
            }
            cout << endl;
        }
    
        void PosOrderNonR()  //后续  非递归
        {
            if (_root == NULL)
                return;
            stack<BinaryTreeNode<T>*> s;
            BinaryTreeNode<T>* cur = NULL;
            BinaryTreeNode<T>* prev = NULL;
            BinaryTreeNode<T>* tmp = NULL;
            s.push(_root);
            while (!s.empty())
            {
                cur = s.top();
                if (prev != cur&&cur->_leftChild != NULL)//1.左不空且prev!=cur 压左
                    s.push(cur->_leftChild);
                else//左空
                {
                    if (cur->_rightChild!=tmp  &&cur->_rightChild)//右不空 且 cur->right!=tmp 压右
                    {
                        s.push(cur->_rightChild);
                    }
    
                    else             //右空  输出 cur
                    {
                        cout << cur->_data << ' ';
                        tmp = s.top();    //tmp(判断是否压右)始终为出栈前的栈顶
                        s.pop();
                        if (!s.empty())
                        {
                            prev = s.top();//prev(判断是否压右)始终为出栈后栈顶
    
                        }
                    }
                }
            }
            cout << endl;
        }
    
    protected://以下为递归的调用函数
    
        BinaryTreeNode<T>* _CreateBiTree(const T* tmp, size_t& index, size_t size)
        {
            BinaryTreeNode<T>* root = NULL;
            if (index < size&&tmp[index]!='#')
            {
                root = new BinaryTreeNode<T>(tmp[index]);
                root->_leftChild = _CreateBiTree(tmp, ++index, size);
                root->_rightChild = _CreateBiTree(tmp, ++index, size);
            }
            return root;
        }
    
        void _InOrder(BinaryTreeNode<T>* &node)
        {
            if (node == NULL)
                return;
            _InOrder(node->_leftChild);
            cout << node->_data << ' ';
            _InOrder(node->_rightChild);
        }
    
        void _PreOrder(BinaryTreeNode<T>* &node)
        {
            if (node == NULL)
                return;
            cout << node->_data<<' ';
            _PreOrder(node->_leftChild);
            _PreOrder(node->_rightChild);
    
        }
    
        void _PosOrder(BinaryTreeNode<T>* &node)
        {
            if (node == NULL)
                return;
            _PosOrder(node->_leftChild);
            _PosOrder(node->_rightChild);
            cout << node->_data << ' ';
        }
    
        int _Size(BinaryTreeNode<T>* root,int & size)
        {
            if (root == NULL)
                return 0;
            size++;
            _Size(root->_leftChild, size);
            _Size(root->_rightChild, size);
            return size;
        }
    
        int _Hight(BinaryTreeNode<T>* root)
        {
            int hight = 1;
            if (root == NULL)
                return 0;
            hight += _Hight(root->_leftChild);
            int ritHight = 0;
            ritHight+= _Hight(root->_rightChild);
            if (hight < ritHight)
                hight = ritHight;
            return hight;
    
    
        }
        void _Destory(BinaryTreeNode<T>* root)
        {
            if (root == NULL)
                return;
            BinaryTreeNode<T>* del = root;
    
            _Destory(del->_leftChild);
            _Destory(del->_rightChild);
            delete root;
    
            return;
        }
    
        void _LeafNum(BinaryTreeNode<T>* root,int& num)
        {
            if (root == NULL)
                return ;
            if (root->_leftChild == NULL&&root->_rightChild == NULL)
                ++num;
            _LeafNum(root->_leftChild,num);
            _LeafNum(root->_rightChild,num);
            return ;
        }
    
        BinaryTreeNode<T>* _Copy(BinaryTreeNode<T>* root)
        {
            if (root == NULL)
                return NULL;
            BinaryTreeNode<T>* newRoot = NULL;
            newRoot = new BinaryTreeNode<T>(root->_data);
            newRoot->_leftChild = _Copy(root->_leftChild);
            newRoot->_rightChild = _Copy(root->_rightChild);
            return newRoot;
    
        }
    };
    

    测试代码

    void CheckBinaryTree(){
        int l[j] = { 1, 2, 3,'#', '#', 4, '#', '#', 5, 6 };
        int s[18] = { 1, 2, 3, 4, '#', '#', 5, '#', '#', 6,'#','#' ,7, 8, '#', '#', 9, 10 };
        BinaryTree<int> t1;
        BinaryTree<int> t2(s, 18);
        BinaryTree<int> t3(t2);
        t1 = t2;
        t2.PreOrder();
        t2.InOrder();
        t2.PosOrder();
        t2.LevelOrder();
        t2.Size();
        t2.Hight();
        t2.Destory();
        t3.InOrder();
        t1.InOrder();
        t3.LeafNum();
        t3.PreOrderNonR();
        t3.InOrderNonR();
        t3.PosOrderNonR();
    }
    

    构造后形成的树如下结构

                             1
                            /  \
                          2     7
                         / \   /  \
                       3    6  8   9
                      / \         /
                    4    5       10
    

    输出:

    pre    : 1 2 3 4 5 6 7 8 9 10
    in     :  4 3 5 2 6 1 8 7 10 9
    post   : 4 5 3 6 2 8 10 9 7 1
    level  : 1 2 7 3 6 8 9 4 5 10
    

    相关文章

      网友评论

          本文标题:二叉树实现

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