问题描述:
一棵树的节点定义格式如下:struct Node{
Node* parent;
Node* firstChild; // 孩子节点
Node* sibling; // 兄弟节点}
要求非递归遍历该树。
解题思路:
使用队列存储遍历的思想:
- 根结点设为哨兵节点。
- 把哨兵节点的所有儿子节点依据从左到右的顺序推入队列中,然后弹出队列头的节点,做为哨兵结点。
- 判断哨兵结点是或为空节点,如果为空,说明队列已经空了遍历结束,否则进行步骤2。
一个用儿子/兄弟链存储的树形结构如图1所示。首先把根结点1的儿子2、3推入队列中,弹出2。把结点2的儿子4、5、6推入队列,弹出3。把节点3的儿子7、8推入队列,弹出4。此时哨兵4无儿子,弹出5。依次弹出8,队列为空了,结束遍历。表1反应了遍历图1所有节点过程。
图1儿子/兄弟链表
表1链表的遍历过程
哨兵 |
推入结点 |
弹出结点 |
队列元素变化 |
1 |
2、3 |
2 |
{}->{2、3}->{3} |
2 |
4、5、6 |
3 |
{3}->{3、4、5、6}->{4、5、6} |
3 |
7、8 |
4 |
{4、5、6}->{4、5、6、7、8}->{5、6、7、8} |
4 |
无 |
5 |
{5、6、7、8}->{5、6、7、8}->{6、7、8} |
5 |
无 |
6 |
{6、7、8}->{6、7、8}->{7、8} |
6 |
无 |
7 |
{7、8}->{7、8}->{8} |
7 |
无 |
8 |
{8}->{8}->{} |
代码实现:
queue<Node*> nodeQueue;//队列对象
void print(Node * );//打印该结点
void printAll(Node * root)
{
Node* temp = root;//初始哨兵为根
while(temp)//结点
{
print(temp);
temp = temp->firstChild;
while(temp)//哨兵儿子推入队列中
{
nodeQueue.push(temp);
temp = temp->sibling;
}
temp = nodeQueue.pop();//重新
}//设置哨兵
}