问题1:
给定一棵二叉树,要求从上到下从左到右分层输出该二叉树的节点值。
问题2:
从左到右输出二叉树中某一层的节点值。
分析与解法:
【解法一】
使用递归的方法。先解问题2,然后用问题2的解法依次遍历其各层节点。于是假设要求访问二叉树中第k层的节点,那么其实可以把它转化成分别访问以该二叉树根节点的左右孩子节点为根节点的两棵子树中层次为k-1的节点。
代码:
typedef struct Node
{
struct Node *lchild;//左孩子指针
struct Node *rchild;//右孩子指针
int data; //节点数值
}
/*问题2*/
int printNodeAtLevel(Node *root, int level)
{
if(root == NULL || level < 0)
return 0;
if(level == 0)
{
cout << root -> data << " ";
return 1;
}
printNodeAtLevel(root -> lchild, level - 1);
printNodeAtLevel(root -> rchild, level - 1);
}
/*问题1*/
void printNodeByLevel(Node *root)
{
for(int level = 0; ; level++)
{
if(!printNodeAtLevel(root, level))
break;
}
}
【解法二】
问题1中对每一层的访问都需要从根节点开始,直到访问完所有的层次,这样的效率较低,可以使用非递归的方法。设置两个指针cur和last用于判定每一层的结束。
代码:
/*问题1*/
void printNodeByLevel(Node *root)
{
if(root == NULL)
return;
vector<Node *> vec;
vec.push_back(root);
int cur = 0;
int last = 1;
while(cur < vec.size())
{
last = vec.size();//定位last于当前行最后一个节点的下一个位置
while(cur < last)//当cur在last之前时
{
cout << root -> data << " ";
if(root -> lchild)
vec.push_back(root -> lchild);
if(root -> rchild)
vec.push_back(root -> rchild);
cur++;//cur后移
}
cout << endl;//当cur与last相等时,说明该层访问结束,换行
}
}
【解法三】
利用了两个队列,一个储存本层的节点,另一个储存下层的节点。遍历本层的节点,把其子代节点排入下层队列。本层遍历完毕后,就可换行,并交换两个队列。
代码:
http://www.cnblogs.com/miloyip/archive/2010/05/12/binary_tree_traversal.html
【解法四】
把一个结束信号放进队列里。由于使用queue,可以插入一个空指针去表示一层的遍历结束。
代码:
http://www.cnblogs.com/miloyip/archive/2010/05/12/binary_tree_traversal.html
【解法五】
用了两个队列。一个队列放节点,一个队列放对应的节点的层次。
代码:
http://www.cnblogs.com/miloyip/archive/2010/05/12/binary_tree_traversal.html
扩展问题:
问题1:
给定一棵二叉树,要求从下到上从左到右分层输出该二叉树的节点值。
问题2:
从右到左输出二叉树中某一层的节点值。
分析与解法:
问题1:
根据书上的代码进行修改,使用栈存放对应的节点的层次。
代码:
http://blog.csdn.net/kindlucy/article/details/5587231
问题2:
层与层之间加入哑元素(NULL),然后逆序输出队列Q。
代码:
http://www.cnblogs.com/DiaoCow/archive/2010/06/01/1749187.html