一、问题描述
将一棵二叉树按层遍历,并将结点依次编号,如下面二叉树的分层遍历结果为:
2
4 6
5 3 7
并编程函数打印指定层结点,根结点为第0层。
二、我先想到的是用队列来记录自身已经打印但子结点尚未打印的结点。
但我并不知道每层应该应该出队多少个(否则需要使用另一个数据结构记录之,或者将NULL也压入队,加大了存储空间)。
实际上队中存储的第k-1层的结点:
#include <iostream> #include <queue> using namespace std; struct Node { Node *pLeft; Node *pRight; int value; }; Node *CreateATree(); void LevelOrder(Node *header); queue<Node*> NodesPrinted; int main() { Node *header = CreateATree(); LevelOrder(header); system("pause"); return 0; } void LevelOrder(Node *header) { int size; if(header != NULL) { cout << header->value << endl; NodesPrinted.push(header); } size = NodesPrinted.size(); while(!NodesPrinted.empty()) { for(int i = 0; i < size; i++) { Node *currentNode = NodesPrinted.front(); NodesPrinted.pop(); if(currentNode->pLeft != NULL) { cout << currentNode->pLeft->value << "\t"; NodesPrinted.push(currentNode->pLeft); } if(currentNode->pRight != NULL) { cout << currentNode->pRight->value << "\t"; NodesPrinted.push(currentNode->pRight); } } size = NodesPrinted.size(); cout << endl; } }
使用STL队列有个蛋疼的地方,queue::pop方法不返回弹出的元素,故而要调用两个函数(不知道为何这样设计 )。
这个算法使用了个辅助数据结构队列。
三、使用递归
实际上就是将问题转化为打印两个子树(得利于树本身就是递归定义的)。
下面代码打印第level层结点并返回结点个数:
int PrintNodesAtLevel(Node *node, int level) { if(level == 0 && node != NULL) { cout << node->value << "\t"; return 1; } else if(level == 0) { return 0; // 不要落了这个返回条件 } else { return PrintNodesAtLevel(node->pLeft, level-1) + PrintNodesAtLevel(node->pRight, level - 1); } }
然后只要计算二叉树的高度,然后打印每层的结点就可以了。
四、大神的分析
http://www.cnblogs.com/miloyip/archive/2010/05/12/binary_tree_traversal.html