二叉树的遍历

二叉树的定义

template<typename T>
class BTNode
{
public:
    T data;
    BTNode<T> *left, *right;
    BTNode(const T& value,BTNode<T>* r =0)
     :data(value),left(l),right(r){}
};

先序遍历

迭代的先序遍历
template<typename T>
void BTNode<T>::recursivePreOrder(BTNode<T>* root)
{
    if(!root)
        return;
    root->visit(root);
    if(root->left)
        recursivePreOrder(root->left);
    if(root->right)
        recursivePreOrder(root->right);
}
循环的先序遍历

循环的先序遍历是就是手动建立一个栈,模拟递归遍历

//添加一个leftVisit操作,每次把某个结点的左子树左结点全部访问一遍后放入栈
template<typename T>
void leftVisit(BTNode<T>* root,stack<BTNode<T>*>& s)
{
    while(root)
    {
        root->visit(root);
        s.push(root);
        if(root->left)
            root = root->left;
        else
            break;
    }
}


template<typename T>
void BTNode<T>::loopPreOrder(BTNode<T> *root)
{

    if(!root)
        return;
    stack<BTNode<T>*> s;
    leftVisit(root,s);//访问该结点以及该结点左子树上所有左孩子
    while(!s.empty())
    {
        BTNode<T> *top = s.top();
        s.pop();
        if(top->right)//左孩子访问结束后访问右孩子
            leftVisit(top->right,s);
    }
}

中序遍历

迭代的先序遍历
template<typename T>
void BTNode<T>::recursiveInOrder(BTNode<T>* root)
{
    if(!root)
        return;
    recursiveInOrder(root->left);
    root->visit(root);
    recursiveInOrder(root->right);
}
循环的先序遍历
template<typename T>
void pushLeftBranch(BTNode<T>* root, stack<BTNode<T>*> &s)
{
    while(root)
    {
        s.push(root);
        root = root->left;
    }
}
template<typename T>
void BTNode<T>::loopInOrder(BTNode<T>* root)
{
    if(!root)
        return;
    stack<BTNode<T>*> s;
    pushLeftBranch(root,s);
    while(!s.empty())
    {
        BTNode<T>* top = s.top();
        s.pop();
        top->visit(top);
        if(top->right)
            pushLeftBranch(top->right,s);
    }
}

后序遍历

迭代的后序遍历
template<typename T>
void BTNode<T>::recursiveInOrder(BTNode<T>* root)
{
    if(!root)
        return;
    recursiveInOrder(root->left);
    recursiveInOrder(root->right);
    root->visit(root);
}


//非递归的后序遍历
/*一个二叉树,先访问其左孩子,再访问右孩子,最后访问根节点
先将父节点全部的左孩子放入栈内,直到该节点一直为空,最后一个节点P的左孩子为空,此时P的右孩子还没有访问,
*/
template<typename T>
void BTNode<T>::loopPostOrder(BTNode<T>* root)
{
    if(!root)
        return;
    stack<BTNode<T>*> s1;//s1用来存储访问的节点
    stack<int> s2;//s2节点用来存储是否可以访问
    while(root||!s1.empty())
    {
        //将root的左子树节点全部放入栈s1中,同时s2中放入0表示当前数据不可访问
        while(root)
        {
            s1.push(root);
            s2.push(0);
            root = root->left;
        }
        if(s1.empty()&&s2.top()==1)
        {
            visit(s1.top()->data);
            s1.pop();
            s2.pop();
        }
        else
        {
            s2.pop();
            s2.push(1);
            root = s1.top()->right;
    }
    }
}

层序遍历

template<typename T>
void BTNode<T>::levelOrder(BTNode<T>* root)
{
    if(!root)
        return;
    queue<BTNode<T>*> q;
    q.push(root);
    while(!q.empty())
    {
        BTNode<T>* x = q.front();
        q.pop();
        x->visit(x);
        if(x->left)
            q.push(x->left);
        if(x->right)
            q.push(x->right);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值