Programe_Of_Beauty:3.10 分层遍历二叉树(另一种实现方法)
2011-05-30 19:41 x_feng 阅读(300) 评论(0) 收藏 举报1.问题定义
给定一棵二叉树,要求按分层遍历该二叉树,即从上到下按层次访问该二叉树(每一层将单独输出一行),每一层要求访问的顺序为从左到右,并将节点依次编号。下面是一个例子:
正确输出为:
1
2 3
4 5 6
7 8
节点定义:
struct Node {
Node *pLeft; //节点数据
Node *pRight; //左指针
int data; //右指针
};
2.编程之美解法
书上举出两个解法。第一个解法是用递归方式,搜寻并打印某一层的节点,再打印下一层的节点。这方法简单但时间效率不高(但不需要额外空间),因此书中亦提供了第二个解法。 书中第二个解法,使用vector容器来储存n个节点信息,并用一个游标变量last记录前一层的访问结束条件,实现如下:
void PrintNodeByLevel(Node* root) {
vector<Node*> vec; // 这里我们使用STL 中的vector来代替数组,可利用到其动态扩展的属性
vec.push_back(root);
int cur = 0;
int last = 1;
while(cur < vec.size()) {
Last = vec.size(); // 新的一行访问开始,重新定位last于当前行最后一个节点的下一个位置
while(cur < last) {
cout << vec[cur] -> data << " "; // 访问节点
if(vec[cur] -> lChild) // 当前访问节点的左节点不为空则压入
vec.push_back(vec[cur] -> lChild);
if(vec[cur] -> rChild) // 当前访问节点的右节点不为空则压入,注意左右节点的访问顺序不能颠倒
vec.push_back(vec[cur] -> rChild);
cur++;
}
cout << endl; // 当cur == last时,说明该层访问结束,输出换行符
}
}
3.别人的解法
详见:http://www.cnblogs.com/miloyip/archive/2010/05/12/binary_tree_traversal.html
4.我的想法
与书上的想法类似,同样设置两个标量,i,j,分别用来记录当前层的节点个数和下一层的节点个数(我想能记录二叉树每层的节点个数,或许多其它算法有用吧)
void PrintNodeByLevel(Node *root)
{
queue<Node*> Q;
if (root != NULL)
{
Q.push(root);
}
else
return;
int i = 1;//用来记录每一层有多少个结点
int j = 0;//用来记录下一层有多少个节点
do{
i--;//i减少一次 说明当前层出去了一个,当i=0时,表示当前层都出队了
Node *node = Q.front();
Q.pop();
cout<<node->data<<" ";//当然这里每层结尾都多输出一个空格" ",你也可以在这里做个判断:if (i != 0),否则就把输出放到i == 0的地方输出
if (node->pLeft != NULL)
{
j++;
Q.push(node->pLeft);
}
if (node->pRight != NULL)
{
j++;
Q.push(node->pRight);
}
if (i == 0)//表示当前层都出队了,输出换行
{
i = j;//把下一层的个数给i
j = 0;
cout<<endl;
}
}while(!Q.empty());
}
空间复杂度为O(m),m为所有层中的最大数量。比书上的vector,O(n),一般情况下少一点。

浙公网安备 33010602011771号