Recursion and non-recursion of binary tree

The access to a tree can be accessed by means of pre-order access, in-order access, post-order access, and layer-order access.
There are two representation methods of binary tree, one is array representation and the other is chain storage method. It is particularly effective to represent a complete binary tree with an array, but it is very time-consuming to represent a general binary tree with an array, so a chain structure is generally used to represent it. According to the definition of a binary tree, the structure of a binary tree can be designed. A binary tree should contain The root node of the tree (_root), left subtree (_lift), right subtree (_right) write picture description here
storage representation of binary linked list
write picture description here

Here, the ideas of pre-order, in-order, and post-order traversal are relatively simple. Control the loop conditions and use recursive methods to call directly. The idea of ​​layer-order traversal is realized by the idea of ​​​​first-in-first-out queue
! [Write here Image description]
Layer order traversal thought diagram ( https://img-blog.csdn.net/20170925091220618?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd3luMTI2/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity /SouthEast )
non-recursion is done with stack assistance

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<assert.h>
#include<queue>
#include<stack>
using namespace std;
template <class T>
struct NodeBinaryTree
{
    NodeBinaryTree(const T& data=T())//定义结构体  并初始化
    :_data(data)
    , _left(NULL)
    , _right(NULL)
    {}
    NodeBinaryTree* _left;
    NodeBinaryTree* _right;
    T _data;
};
template <class T>
class BinaryTree
{
    typedef NodeBinaryTree<T> Node;
public:
    BinaryTree()//无参构造函数
        :_root(NULL)
    {}
    BinaryTree(const T* arr, int sz, const T invalid)//带有参数的构造函数
    {
        assert(arr);
        int index = 0;//代表数组的初始位置
        _root = CreatTree(arr, sz, invalid, index);
    }
    BinaryTree(const BinaryTree<int> & bt)
    {
        _root = Copy(bt._root);
    }
    BinaryTree<T> operator=(const BinaryTree<T> &bt) //赋值运算符重载
    {
        if (this != &bt)
        {
            Node* tmp = bt._root;
            delete[] bt;
            _root = tmp;
        }
        return *this;
    }
    //BinaryTree<T> operator=(const BinaryTree<T> &bt)//现代写法
    //{
    //  std::swap(_root, bt._root)
    //      return *this;
    //}
    ~BinaryTree()
    {
        if (_root)
        {
            delete[]_root;
            _root = NULL;
        }
    }
    //递归思想实现二叉树
     void PreOrder()
    {
         cout << "前序遍历";
             _PreOrder(_root);
    }
     void InOrder()
     {
         cout << "中序遍历";
             _InOrder(_root);
     }
     void EndOrder()
     {
         cout << "后序遍历";
             _EndOrder(_root);
     }
     void SeqOrder()
     {
         cout << "层序遍历";
             _SeqOrder(_root);
     }
     size_t Size()
     {
         return _Size(_root);
     }

     size_t Depth()
     {
         return _Depth(_root);
     }
     size_t LeafSize()
     {
         return _LeafSize(_root);
     }
     size_t GetKLevel_NodeSzie(int k)
     {

        return  _GetKLevel_NodeSzie(_root, k);
     }
     void Destory()
     {
         _Destory();
     }

protected:
    Node* CreatTree(const T*arr,int  sz, const T& invalid,int&  index)//前序遍历建立二叉树
    {
        assert(arr);
        if ((index <sz) && arr[index] != invalid)
        {
            Node* _root = new Node(arr[index]);
            _root->_left = CreatTree(arr, sz, invalid, ++index);
            _root->_right = CreatTree(arr, sz, invalid, ++index); 
            return _root;
        }
        return NULL;
    }
    Node* Copy(Node* _root)
    {
        Node* tmp = NULL;
        if (_root)
        {
            tmp = new Node(_root->_data);
            tmp->_left = Copy(_root->_left);
            tmp->_right = Copy(_root->_right );
            return tmp;
        }
    }
    void _PreOrder(Node* _root)
    {
        if (_root)
        {
            cout << _root->_data<<"->";
            _PreOrder(_root->_left);
            _PreOrder(_root->_right);
        }
    }
    void _InOrder(Node* _root)
    {
        if (_root)
        {
            _InOrder(_root->_left);
            cout << _root->_data << "->";
            _InOrder(_root->_right);
        }
    }
    void _EndOrder(Node* _root)
    {
        if (_root)
        {

            _EndOrder(_root->_left);
            _EndOrder(_root->_right);
            cout << _root->_data << "->";
        }
    }
    void _SeqOrder(Node* _root)//层序遍历  层序遍历是以队列的思想来实现的(画图)
    {
        queue<Node*> q;
        if (_root)
        {
            q.push(_root);
         }
        while (!q.empty())//当队列不为空时,进入循环打印
        {
            Node* tmp = q.front();
            cout << tmp->_data<<"->";
            q.pop();
            if (tmp->_left)
            {
                q.push(tmp->_left);
            }
            if (tmp -> _right)
            {
                q.push(tmp->_right);
            }

        }

    }
    size_t _Size(Node* _root)//不需要定义计数器 浪费空间  直接用递归计算
    {
        if (_root == NULL)
        {
            return 0;
        }
        if (_root)
        {
            return _Size(_root->_left) + _Size(_root->_right) + 1;
        }
    }
    size_t _Depth(Node* _root)//  左右子树高的+1依次递归
    {
        if (_root == NULL)
        {
            return 0;
        }
        if (_root)
        {
            return (_Depth(_root->_left) > _Depth(_root->_right) 
                ? _Depth(_root->_left) : _Depth(_root->_right)) + 1;
        }
    }
    size_t _LeafSize( const Node* _root)//返回二叉树中叶子节点的个数 三种情况都要分别考虑到
    {
        if (_root == NULL)
        {
            return 0;
        }
        if ((_root->_left == NULL) && (_root->_right==NULL))
        {
            return 1;
        }
        if (_root)
        {
            return _LeafSize(_root->_left) + _LeafSize(_root->_right);
        }
    }
    size_t _GetKLevel_NodeSzie( Node* _root,int k)//返回第k层节点的个数
    {
        if (_root == NULL)
        {
            return 0;
        }
        if (k==1)
        {
            return 1;
        }
        return _GetKLevel_NodeSzie(_root->_left, k - 1)
            + _GetKLevel_NodeSzie(_root->_right, k - 1);
    }

public:
    //用栈做辅助非递归实现二叉树
    void PrevOrder_NonR()
    { 
        Node* cur = _root;
        stack<Node*> s;
        while (cur || !s.empty())
        {
            while (cur)
            {
                cout << cur->_data << "->";
                s.push(cur);
                cur = cur->_left; 
            }
            Node*top= s.top();
            s.pop();
            cur = top->_right;

        }

    }
    void InOrder_NonR()//中序遍历
    {
        Node* cur = _root;
        stack<Node*> s;//在这里要定义成一个结构体 若定义成一个整型无法访问下一个节点  以便可以找到下一个节点
        while (cur || !s.empty())
        {
            while (cur)
            {
                s.push(cur);
                cur = cur->_left;
            }
            Node* top = s.top();
            cout << top->_data << "->";
            s.pop();
            cur = top->_right;
         }
    }


    void EndOrder_NonR()//后续遍历,需要定义一个指向前一个节点的指针
    {
        Node* cur = _root;
        stack<Node*> s;
        Node* prev = NULL;
        while (cur || !s.empty())
        {
            while (cur)
            {
                s.push(cur);
                cur = cur->_left;
            }
            Node* top = s.top();
            if (((top->_right) == NULL) ||( top->_right == prev))
            {
                cout << top->_data<<"->";
                s.pop();
                prev=top;
            }
            else
                cur = top->_right;
        }

    }
    void _Destory(Node* &_root)
    {
        if (_root == NULL)
        {
            return 0;
        }
        else
        {
            _Destory(_root->left);
            _Destory(_root->right);
            delete _root;
            _root = NULL;
        }

    }

 protected:
     Node* _root;
//
};
void TestBinaryTree()
{
    //int arr[10] = { 1, 2, 3, '#', '#', 4, '#', '#', 5, 6 };
    int arr[15] = {1,2,'#',3,'#','#',4,5,'#',6,'#',7,'#','#',8}; 

    int sz = sizeof(arr) / sizeof(arr[0]);
    //BinaryTree<int> bt;
    BinaryTree<int> bt1(arr, sz, '#');
    //BinaryTree<int>bt2(bt1);
    //BinaryTree<int>bt = bt1;

    bt1.PreOrder();
    cout << endl;
    bt1.InOrder();
    cout << endl;
    bt1.EndOrder();
    cout << endl;
    bt1.SeqOrder();
    cout << endl;
    cout << "Size()?  " << bt1.Size() << endl;
    cout << "Depth()?  " << bt1.Depth()<<endl;
    cout << "LeafSize()?  " << bt1.LeafSize()<<endl;
    cout << "GetKLevel_NodeSzie()?  " << bt1.GetKLevel_NodeSzie(3) << endl;


    bt1.PrevOrder_NonR();
    cout << endl;
    bt1.InOrder_NonR();
    cout << endl;
    bt1.EndOrder_NonR();
    cout << endl;

}
int main()
{
    TestBinaryTree();
    system("pause");
    return 0;
}

write picture description here

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326516669&siteId=291194637