编程之美读书笔记_3.10 分层遍历二叉树

本文介绍了一种改进的二叉树分层遍历算法,解决了原有算法中输出格式的问题,并通过精简代码提高了效率。文章提供了两种实现方式,一种保留所有节点,另一种则在遍历过程中不保存中间结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 原文链接:http://blog.youkuaiyun.com/flyinghearts/archive/2010/05/25/5624081.aspx

3.10 分层遍历二叉树

 

看到Milo写的这篇文章,又翻了下书,发现书的代码(P253)有个瑕疵,每个节点值后面都会显示一个空格,如果将间隔字符改为“-”,输出的每行最后都有一个“-”,不能达到要求。不过,只要将 cout << vec[cur] -> data << " ";

这行改为:

if (cur==last-1) cout << vec[cur] -> data << "/n";

else cout << vec[cur] -> data << " ";

即可修正这个问题。

 

书上的代码用了两个while循环,可以精简为一个。

思路:保存每层的最后一个节点位置(取节点的地址或在容器内的位置),当遍历到该位置时,获取下一层最后一个节点的位置,如果这两个位置相同,说明已经遍历完全部节点,否则开始下一层的遍历。

由于不知道树的节点数,很多情况下,容器采用deque比采用vector性能更佳,因为避免了申请内存后对原数据的拷贝。另外,再考虑到deque的数组下标访问要比采用迭代器访问慢很多,最好采用迭代器来访问内部数据。

 

  1. struct Node {  
  2.   Node *left;  
  3.   Node *right;  
  4.   int data;  
  5. };  
  6. void print_tree_bfs_d(Node* root) {  
  7.   if (root==NULL) return;  
  8.   deque<Node*> tree;  
  9.   tree.push_back(root);  
  10.   deque<Node*>::iterator low=tree.begin(),last=tree.begin();  
  11.   Node *node=root;  
  12.   while (1){  
  13.     if (node->left)  tree.push_back(node->left);  
  14.     if (node->right) tree.push_back(node->right);  
  15.     if (low!=last){  
  16.       cout << node->data << " ";  
  17.     }else{  
  18.       cout<< node->data << "/n";  
  19.       if (last==tree.end()-1) break;  
  20.       last=tree.end()-1;  
  21.     }  
  22.     node=*++low;  
  23.   }  
  24.   cout<< "/n";  
  25. }  

 

 

上面的代码,保留了树的所有全部节点,稍做修改(比如用一个数组记录每层的最后一个节点的位置),可以查询某层的所有节点。如果不需要保存中间结果,可以修改为:

 

 

  1. void print_tree_bfs_dq(Node* root) {  
  2.   if (root==NULL) return;  
  3.   deque<Node*> tree;  
  4.   tree.push_back(root);  
  5.   deque<Node*>::iterator low=tree.begin();  
  6.   Node *node=root, *last=root;  
  7.   while (1){  
  8.     node=tree.front();  
  9.     tree.pop_front();  
  10.     if (node->left)  tree.push_back(node->left);  
  11.     if (node->right) tree.push_back(node->right);  
  12.     if (node!=last){  
  13.       cout << node->data << "-";  
  14.     }else{  
  15.       cout<< node->data << "/n";  
  16.       if (tree.empty()) break;  
  17.       last=tree.back();  
  18.     }  
  19.   }  
  20.   cout<< "/n";  
  21. }  

 

 

当然也可以用queuequeue只是对deque的封装)。

 

对问题2,上面的代码只要做稍微修改,只在遍历到所要求的层才输出,输出后直接返回就可以了。

 

 

完整程序(含测试例子)

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值