您的位置:首页 > 其它

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

2012-06-19 21:41 393 查看
书中解法三用数组来对树进行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;
}



from: http://hi.baidu.com/azuryy/blog/item/1916d5f33a0f61cd0a46e081.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  扩展 null iterator 算法