数据结构和算法经典100题-第16题

第16题
题目:输入一颗二元树,从上往下按层打印树的每个结点,同一层中按照从左往右的顺序打印。
例如输入
8
/ /
6 10
// //
5 7 9 11
输出8 6 10 5 7 9 11。


题目分析:
从题目中可以看出,要求的遍历顺序不是前序、中序或后序遍历树。树是通过递归定义的,正常递归方法不能实现要求中的遍历顺序。按照要求每次都是从同一层的最左遍历到树的最右。下一层都是按照同一节点的孩子的顺序遍历。如遍历第三层是按照第二层各结点左右孩子的顺序,先遍历6的左右孩子,然后遍历10的左右孩子这样。于是我们想到用一个队列将树上的各个结点缓存起来依次遍历。分析到这里这个问题基本已经解决了。

那么上代码:

#include <stdio.h>
#include <deque>
#include <iostream>

using namespace std;

// 结点
struct Node {
    int value;
    Node* left;
    Node* right;
};

// 二叉树
class BinaryTree {
public:
    BinaryTree(Node* root) : m_root(root) { };
    ~BinaryTree() { };

    int levelTraverse();

    /* data */
private:
    Node* m_root;
    deque<Node*> m_queue;
};

// 层序遍历
int BinaryTree::levelTraverse()
{
    if (NULL == m_root) {
        return -1;
    } 

    m_queue.push_back(m_root);

    Node* tmp = m_queue.front();

    while(NULL != tmp) {
        m_queue.pop_front();
        cout<<"value = "<<tmp->value<<endl;
        if (NULL != tmp->left) {
            m_queue.push_back(tmp->left);    
        }
        if (NULL != tmp->right) {
            m_queue.push_back(tmp->right);    
        }

        if (0 < m_queue.size())
        {
            tmp = m_queue.front();
        }
        else
        {
            return -1;
        }

    }

    return 0;
}

测试程序:

// 用于构造树
void Link(Node* obj, int parrent, int left, int right) {

    if (-1 != left) {
        obj[parrent].left = &obj[left];
    }

    if (-1 != right) {
        obj[parrent].right = &obj[right];
    }

    return ;
}

int test_16() {

/* tree like:

          0
        /    \
      1        2
     / \      / \
    3   4    5   6
   /          \
  7            8
*/
    Node obj_1[9];
    memset(obj_1, 0, sizeof(Node)*9);

    for (int i = 0; i < 9; i++) {
        obj_1[i].value = i;
        obj_1[i].left = NULL;
        obj_1[i].right = NULL;
    }

    Link(obj_1, 0, 1, 2);
    Link(obj_1, 1, 3, 4);
    Link(obj_1, 2, 5, 6);
    Link(obj_1, 3, 7, -1);
    Link(obj_1, 5, -1, 8);

    BinaryTree tree(&obj_1[0]);
    if (!tree.levelTraverse()) {
        cout<<"error"<<endl;
        return -1;
    }

    return 0;
}

int main(int argc, char const *argv[])
{
    test_16();
    return 0;
}

测试结果:

//GD bgl-pub2:/home/d5000/kedong/src/platform/personal_test/liyang/practice_alg % ./16th 
value = 0
value = 1
value = 2
value = 3
value = 4
value = 5
value = 6
value = 7
value = 8

路漫漫吾修远兮,吾将上下而求索…

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值