3.10 分层遍历二叉树 扩展问题一、二

书中解法三用数组来对树进行BFS,比较适合在比赛中使用,如果使用队列的话,当数据规模比较大的时候,频繁的进队列,出队列还是很耗时的。 比较经典的“聪明的打字员”一题,就是BFS搜索,但是数据规模比较大,用队列的话很容易超时,参考PKU1184.

扩展问题一、二是按深度从下到上遍历二叉树,从左向右或者从右向左。
我们可以在开始根节点遍历的时候,每层遍历结束之后,存放一个 NULL 作为层与层之间的分割,当整棵树遍历完之后,再从后向前遍历数组,遇到 NULL 表示当前层结束,这样就可以实现按深度从下到上的遍历。

算法的时间复杂度与按深度从上到下时间复杂度相同,空间多用了4*H Bytes ( H 为树的高度 )

#include <vector>
#include <iostream>

using namespace std;

struct node
{
    node* left;
    node* right;
    int value;
    node( int v ): value( v ),left(NULL),right(NULL) {};
};
vector<const node*> vec;

void steps( const node* root, bool fromLeftToRight )  //true: 从左往右遍历 //false: 从右往左遍历
{
    int cur = 0;
    int last;
    vec.clear();
    vec.push_back( root );

    while ( cur < vec.size() )
    {
        last = vec.size();
        vec.push_back( NULL );  //层与层之间的分割

        while( cur < last )
        {
            if ( fromLeftToRight )
            {
                if ( vec[cur]->right )
                    vec.push_back(vec[cur]->right);
                if ( vec[cur]->left )
                    vec.push_back( vec[cur]->left);
            }
            else
            {
                if ( vec[cur]->left )
                    vec.push_back( vec[cur]->left );
                if ( vec[cur]->right )
                    vec.push_back( vec[cur]->right );
            }
            cur++;
        }
        cur += 1 ;  //跳过层与层之间的NULL节点
    }

    //反向遍历数组
    vector<const node*>::const_reverse_iterator cri;

    for( cri = vec.rbegin() + 1; cri != vec.rend(); cri++ )
    {
        if ( !*cri )
        {
            cout << endl;
        }
        else
        {
            cout << (*cri)->value << " " ;
        }
    }
    cout << endl;
}
书中的 test case:

int main()
{
    node* root = new node(1);
    node* tmp = new node(2);
    root->left = tmp;
    tmp = new node(3);
    root->right = tmp;

    tmp = new node(4);
    root->left->left = tmp;
    tmp = new node(5);
    root->left->right = tmp;

    tmp = new node(6);
    root->right->right = tmp;

    tmp = new node(7);
    root->left->right->left = tmp;

    tmp = new node(8);
    root->left->right->right = tmp;

    cout << "From Left To the Right " << endl;
    steps(root,true);

    cout << "From Right To the Left " << endl;    
    steps(root,false);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值