分层遍历二叉树

题目:对于一个给定的二叉树,分层遍历二叉树,分为上下左右,不同方向进行遍历。

解析:原来实现时考虑使用队列来做,但这个算法不方便使用递归来做,如果使用递归会造成诸多问题。因此可以使用循环来处理,编程之美中不使用队列而是用数组模拟队列,对于从下上输出很有帮助,具体描述如下:

1)对于从右向左输出,开始考虑使用栈来颠倒,实际发现其实只要处理左右子树的顺序改变一下就可以了;

2)对于从下向上遍历,开始考虑使用栈来存储再输出,但这样付出额外的空间,因为采用了数组保存了特定输出顺序的所有节点,只要从后向前输出数组,就可以实现从下向上的遍历了。

心得:使用数组来保存待输出的节点顺序,可以方便按照需求进行合理的输出,其实就是改变遍历数组的顺序就可以了。

具体的程序代码如下:


#include <stdio.h>
#include <vector>
class TreeNode {
 public:
  TreeNode() : left_(NULL), right_(NULL) {}
  int value_;
  TreeNode* left_;
  TreeNode* right_;
};
void TopDownLeftRightVisit(TreeNode* root) {
  std::vector<TreeNode*> visit_order;
  int offset = 0;
  TreeNode* current = root;
  if (current) {
    visit_order.push_back(current);
  }
  while (offset < visit_order.size()) {
    printf("%d ", visit_order[offset]->value_);
    current = visit_order[offset];
    if (current->left_) {
      visit_order.push_back(current->left_);
    }
    if (current->right_) {
      visit_order.push_back(current->right_);
    }
    offset++;
  }
}
void TopDownRightLeftVisit(TreeNode* root) {
  std::vector<TreeNode*> visit_order;
  int offset = 0;
  TreeNode* current = root;
  if (current) {
    visit_order.push_back(current);
  }
  while (offset < visit_order.size()) {
    printf("%d ", visit_order[offset]->value_);
    current = visit_order[offset];
    if (current->right_) {
      visit_order.push_back(current->right_);
    }
    if (current->left_) {
      visit_order.push_back(current->left_);
    }
    offset++;
  }
}
void BottomUpLeftRightVisit(TreeNode* root) {
  std::vector<TreeNode*> visit_order;
  int offset = 0;
  TreeNode* current = root;
  if (current) {
    visit_order.push_back(current);
  }
  while (offset < visit_order.size()) {
    current = visit_order[offset];
    if (current->right_) {
      visit_order.push_back(current->right_);
    }
    if (current->left_) {
      visit_order.push_back(current->left_);
    }
    offset++;
  }
  for (int i = visit_order.size() - 1; i >=0; --i) {
    printf("%d ", visit_order[i]->value_);
  }
}
void BottomUpRightLeftVisit(TreeNode* root) {
  std::vector<TreeNode*> visit_order;
  int offset = 0;
  TreeNode* current = root;
  if (current) {
    visit_order.push_back(current);
  }
  while (offset < visit_order.size()) {
    current = visit_order[offset];
    if (current->left_) {
      visit_order.push_back(current->left_);
    }
    if (current->right_) {
      visit_order.push_back(current->right_);
    }
    offset++;
  }
  for (int i = visit_order.size() - 1; i >=0; --i) {
    printf("%d ", visit_order[i]->value_);
  }
}
void SetLink(TreeNode* parent, TreeNode* left, TreeNode* right) {
  parent->left_ = left;
  parent->right_ = right;
}
int main(int argc, char** argv) {
  TreeNode* tree = new TreeNode[8];
  for (int i = 0; i < 8; ++i) {
    tree[i].value_ = i + 1;
  }
  SetLink(&tree[0], &tree[1], &tree[2]);
  SetLink(&tree[1], &tree[3], &tree[4]);
  SetLink(&tree[2], NULL, &tree[5]);
  SetLink(&tree[4], &tree[6], &tree[7]);  
  TopDownLeftRightVisit(tree);
  printf("\n");
  TopDownRightLeftVisit(tree);
  printf("\n");
  BottomUpLeftRightVisit(tree);
  printf("\n");
  BottomUpRightLeftVisit(tree);
  printf("\n");
}

为了程序设计的简单,没有使用模板,而使用int来表示测试数据。

参考文献:

编程之美3.10

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值