要求使用广度优先遍历时,按行打印二叉树。
在我的理解中,按行打印的关键就是找出换行的条件,也就是找到每一行最后一个节点。
那么从根节点开始,当根节点出队列之后,根节点的子节点就要入队列,而且入队列的是第二层最靠右的子节点。那么依次类推,当第二层最后一个节点出队列时,入队列的也肯定是第三层最靠右的结点,即使第二层最后一个节点没有子节点,最新入队列的节点依然是第三层最靠右的节点。我们可以根据这个特点设定两个指针,last和nlast。
由上面的性质开始推导整个过程:
- 根节点入队列。设last为根节点,nlast为最新加入的节点。
- 根节点出队列,根节点的子节点入队列,此时入队列的是第二层最靠右的节点。此时被设定为last的根节点出队列,入队列的被设定为nlast。当last的节点出队列时,换行,且更新last为第二行最靠右的节点,即nlast。
- 第二层的第一个节点出队列,更新nlast为最新入队的节点,若是出队列的节点为last那么,就换行并且更新last。否则就表示出队列的元素不是第二行最靠右的节点。以此类推
输入:
1248##9##5##36##7##
打印:
1
2 3
4 5 6 7
8 9
#include <iostream>
#include <queue>
using namespace std;
typedef char datatype;
typedef struct Node
{
datatype data;
Node* lchile;
Node* rchile;
}*BiTree,Node;
void OutputData(datatype ch, int level)
{
cout << "第" << level << "层元素是" << ch << endl;
}
void OutputData(datatype ch)
{
cout << "遍历元素为" << ch << endl;
}
void CreateBiTree(BiTree *T)
{
/*这里的T是(BiTree *)类型的指针,故(*T)是BiTree类型的指针,lchild,rchild都是BiTree类型变量*/
/*BiTree *T 就相当于Node** T。*/
datatype ch;
cin >> ch;
if (ch == '#')
{
*T = NULL;
}
else
{
*T = (BiTree)malloc(sizeof(Node));
if (!*T)
exit(OVERFLOW);
else
{
(*T)->data = ch;
CreateBiTree(&(*T)->lchile);
CreateBiTree(&(*T)->rchile);
}
}
}
void breadthFirstSearch(BiTree T)
{
queue<BiTree> nodequeue;
BiTree node;
nodequeue.push(T);
BiTree last=T;
BiTree nlast=T;
while (!nodequeue.empty())
{
node = nodequeue.front();
nodequeue.pop();
cout<<node->data<<" ";
if (node->lchile)
{
nodequeue.push(node->lchile);
nlast = node->lchile;
}
if (node->rchile)
{
nodequeue.push(node->rchile);
nlast = node->rchile;
}
if (last == node)
{
cout << "\n";
last = nlast;
}
}
}
int main()
{
int level = 1;
BiTree bitree = NULL;
CreateBiTree(&bitree);
breadthFirstSearch(bitree);
}