层序遍历二叉树
算法思想:
我们可以利用队列先进先出的性质。层序遍历即应该先打印根节点,从根节点开始分析,为了接下来能够打印值为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(); }
测试结果: