层序遍历二叉树
算法思想:
我们可以利用队列先进先出的性质。层序遍历即应该先打印根节点,从根节点开始分析,为了接下来能够打印值为1的节点的两个子节点,再遍历到该节点时把其左右节点即2和5的两个节点保存在一个队列
中,现在队列
中就有了两个节点。按照从左到右的打印要求,取出节点值为2的节点,打印出值为2的节点之后把它的值为3和4的两个节点放入队列
。此时队列
中就会有三个节点,值为5,3,4。接下来从队列中取出值为5的节点。如此依次进行。
层序打印{ 1, 2, 3,
'#', '#', 4,
'#', '#', 5, 6 }
步骤
|
操作
|
队列
|
1
|
打印节点1
|
节点2、节点5
|
2
|
打印节点2
|
节点5、节点3、节点4
|
3
|
打印节点5
|
节点3、节点4、节点6
|
4
|
打印节点3
|
节点4、节点6
|
5
|
打印节点4
|
节点6
|
6
|
打印节点6
|
|
可以看出:每次打印一个节点的时候,如果该节点有子节点,则把该节点的子节点放到一个队列的末尾。接下来到队列的头部取出最早进入队列的节点,重复前面的打印操作,直到队列中的所有节点度被打印出来。
代码实现:
#include
#include
using namespace std;
template
struct BinaryTreeNode
{
BinaryTreeNode* _left;
BinaryTreeNode* _right;
T _data;
BinaryTreeNode(const T& x)
:_left(NULL)
, _right(NULL)
, _data(x)
{}
};
template
class BinaryTree
{
typedef BinaryTreeNode Node;
public:
BinaryTree()
:_root(NULL)
{}
~BinaryTree()
{
Destroy(_root);
}
void Destroy(Node* root)
{
if (root == NULL)
return;
Destroy(root->_left);
Destroy(root->_right);
delete root;
}
BinaryTree(T* a, size_t n, const T& invalid)
{
size_t index = 0;
_root = _CreateTree(a, n, invalid, index);
}
void LevelOrder() //利用队列实现
{
queue p;
if (_root)
p.push(_root);
while (p.size())
{
Node* front = p.front();
cout << front->_data << " "; //打印节点
if (front->_left)
p.push(front->_left);
if (front->_right)
p.push(front->_right);
p.pop();
}
cout << endl;
}
protected:
Node* _CreateTree(T* a, size_t n, const T& invalid, size_t& index)
{
Node* root = NULL;
if ((index < n) && a[index] != invalid)
{
root = new Node(a[index]);
root->_left = _CreateTree(a, n, invalid, ++index);
root->_right = _CreateTree(a, n, invalid, ++index);
}
return root;
}
protected:
Node* _root;
};
void Test()
{
int a[] = { 1, 2, 3, '#', '#', 4, '#', '#', 5, 6 };
BinaryTree s(a, sizeof(a) / sizeof(a[0]), '#');
s.LevelOrder();
}
测试结果: