非递归二叉树

由于栈和递归原理相同,且递归创建二叉树的效率较低,所以我们可以借助栈来实现二叉树的非递归创建以及遍历。

#include<iostream>
#include<stack>
using namespace std;

template <class T>
struct BinaryTreeNode
{
    BinaryTreeNode* _left;
    BinaryTreeNode* _right;
    T _data;
    BinaryTreeNode(const T &x)
        : _data(x)
        , _left(NULL)
        , _right(NULL)
    {}
};

template<class T>
class BinaryTree
{
    typedef BinaryTreeNode<T> Node;
public:
    BinaryTree()
        :_root(NULL)
    {}

    BinaryTree(const T* arr, size_t size, const T &invalid)
    {
        size_t index = 0;
        _root = _CreateBinaryTree(arr,size,index,invalid);
    }

    void PrevOrder()    //  前序遍历
    {
        Node* root = _root;
        stack<Node*> s;
        s.push(root);
        while (!s.empty())
        {
            Node* pCur = s.top();
            cout << pCur->_data<<" ";
            s.pop();
            if (pCur->_right)
                s.push(pCur->_right);
            if (pCur->_left)
                s.push(pCur->_left);
        }
        cout << endl;
    }

    void InOrder()  //中序遍历
    {
        stack<Node*> s;
        Node* pCur = _root;
        while (pCur || !s.empty())
        {
            while (pCur)    //依次保存左孩
            {
                s.push(pCur);
                pCur = pCur->_left;
            }

            pCur = s.top();
            cout << pCur->_data << " ";
            s.pop();

            //若右孩存在,当成一颗新树来遍历
            pCur = pCur->_right;
        }
        cout << endl;
    }

    void BackOrder()    //后序遍历
    {
        stack<Node*>s;
        Node* pCur = _root;
        Node* flag = NULL; //标志位
        while (pCur || !s.empty())
        {
            while (pCur) //依次保存左孩
            {
                s.push(pCur);
                pCur = pCur->_left;
            }
            pCur = s.top();
            if (pCur->_right == NULL || pCur->_right == flag)
            {
                cout << pCur->_data << " ";
                s.pop();
                flag = pCur;
                pCur = NULL;//防止遍历到根部时,栈为空,而跟的右孩子依旧为真造成的死循环问题
            }
            else
            {
                pCur = pCur->_right;
            }
        }
        cout << endl;
    }
protected:
    Node* _CreateBinaryTree(const T* arr, size_t size, size_t index, const T &invalid)
    {
        stack<Node*> s;
        int flag = 1;
        Node*root = new Node(arr[index++]);
        s.push(root);
        Node* cur = NULL;
        Node* tmp = NULL;
        while (index < size)
        {
            if (flag == 1)  //创建左树
            {
                if (arr[index] == invalid)  //若左树位置无效,flag设为2,创建右树
                {
                    flag = 2;
                }
                else
                {
                    cur = new Node(arr[index]);
                    tmp = s.top();
                    tmp->_left = cur;
                    s.push(cur);
                }
            }
            else if (flag == 2)
            {
                if (arr[index] == invalid)  //若右树位置无效,flag设为3,准备出栈
                {
                    flag = 3;
                }
                else
                {
                    cur = new Node(arr[index]);
                    tmp = s.top();
                    tmp->_right = cur;
                    s.push(cur);
                    flag = 1;   //右树创建完毕后flag设为1,下次接着创建左树
                }
            }
            else
            {
                if (!s.empty()) //若栈非空,依次出栈判断
                {
                    tmp = s.top();
                    s.pop();
                }
                //如果已经出栈的元素是当前栈顶的右孩子,表示此结点左右子树已经创建完毕,继续出栈
                while ((!s.empty()) && (tmp == (s.top()->_right)))
                {
                    tmp = s.top();
                    s.pop();
                }
                flag = 2;
                index--; 
            }
            index++;
        }
        return root;
    }
private:
    Node* _root;
};
 void test()  
{
    int arr[] = { 1, 2, 3, '#', '#',4,'#','#', 5, 6 ,'#','#',7};
    size_t sz = sizeof(arr) / sizeof(arr[0]);
    BinaryTree<int>t(arr, sz, '#');
    t.PrevOrder();
    t.InOrder();
    t.BackOrder();
}

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

这里写图片描述
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Fly_bit

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值