题目:实现一颗二叉树的层序遍历
一、二叉树(Binary Tree)的定义:
二叉树是另一种树型结构,它的特点是每个结点至多只有两棵子树,(即二叉树中不存在度大于2的结点),并且二叉树的子树有左右之分,其次序不能任意颠倒。
二、二叉树的性质:
1、在二叉树的第i层上至多有2^(i-1)个结点(i>=1);
2、深度为k的二叉树至多有2^k - 1个结点,(k>=1);
3、对任何一棵二叉树T,如果其终端结点数为
4、具有n个结点的完全二叉树的深度为
三、层序遍历
按照二叉树的层序次序(即从根结点层到叶结点层),同一层中按先左子树后再右子树的次序遍历二叉树。因此:在所有未被访问结点的集合中,排列在已访问结点集合中最前面结点的左子树的根节点将最先被访问,然后是该节点的右子树的根节点。
层序遍历算法:
1)、初始化一个队列
2)、把根节点的指针入队列
3)、当队列非空时,循环执行以下步骤
》出队列取一个结点
》若该节点的左子树非空,将该节点的左子树指针入队列;
》若该节点的右子树非空,将该节点的右子树指针入队列。
4)、结束。
代码如下:
#pragma once
#include<stdlib.h>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
template<class T>
struct BinaryTreeNode //创建树中的每个结点
{
BinaryTreeNode(const T& data)
:_data(data)
,_pLeft(NULL)
,_pRight(NULL)
{}
T _data; //结点的值
BinaryTreeNode<T>* _pLeft; //左孩子
BinaryTreeNode<T>* _pRight; //右孩子
};
template<class T>
class BinaryTree
{
typedef BinaryTreeNode<T> Node;
public:
BinaryTree()
:_pRoot(NULL)
{}
//构造函数
BinaryTree(const T array[], size_t size, const T& invalid) //按照前序遍历创建一棵树
{
//创建树 ->根结点->左子树->右子树
size_t index = 0; //引用要被初始化
_CreateTree(_pRoot, array, size, invalid, index);
}
//拷贝构造函数--按照前序遍历再创建一棵树
BinaryTree(const BinaryTree<T>& t)
{
_pRoot = _CopyBinaryTree(t._pRoot);
}
//赋值--拷贝一个一样的树
BinaryTree<T>& operator=(const BinaryTree<T>& t)
{
if (this != &t)
{
_DestroyTree(_pRoot);
_pRoot = _CopyBinaryTree(t._pRoot);
}
return *this;
}
//先序遍历
void PreOrder()
{
cout << "PreOrder: " << endl;
_PreOrder(_pRoot);
cout << endl;
}
//层序遍历
void LevelOrder()
{
cout << "LevelOrder: " << endl;
_LevelOrder(_pRoot);
cout << endl;
}
~BinaryTree()
{
_DestroyTree(_pRoot);
}
private:
void _CreateTree(Node *& pRoot, const T array[], size_t size, const T& invalid, size_t& index)
//Node *& pRoot是因为_pRoot已经是一个指针了,需要二级指针或一级指针的引用接收
//因为结点的index是需要被带回的,所以为了改变外部实参要传引用
{
if ((index < size) && (array[index] != invalid)) //index<size条件在前先保证index不越界
{
//1)、创建根结点
pRoot = new Node(array[index]);
//2)、创建根结点的左子树
_CreateTree(pRoot->_pLeft, array , size, invalid, ++index);
//3)、创建根结点的右子树
_CreateTree(pRoot->_pRight, array, size, invalid, ++index);//递归后退时index的值未发生改变
}
} //O(2n+1)->O(n)
Node* _CopyBinaryTree(Node* pRoot)
{
Node* pNewNode = NULL;
if (NULL != pRoot)
{
Node* pNewNode = new Node(pRoot->_data);
pNewNode->_pLeft = _CopyBinaryTree(pRoot->_pLeft);
pNewNode->_pRight = _CopyBinaryTree(pRoot->_pRight);
}
return pNewNode;
}
void _DestroyTree(Node*& pRoot)
{
if (pRoot)
{
_DestroyTree(pRoot->_pLeft);
_DestroyTree(pRoot->_pRight);
delete pRoot;
pRoot = NULL;
}
}
void _PreOrder(Node* pRoot) //先序遍历:根-左子树-右子树
{
if (pRoot)
{
cout << pRoot->_data << " ";
//遍历左子树
_PreOrder(pRoot->_pLeft);
//遍历右子树
_PreOrder(pRoot->_pRight);
}
}
void _LevelOrder(Node* pRoot) //层序遍历:
{
if (NULL == _pRoot)
return;
cout << "LevelOrder:" << endl;
queue<Node*> q;
q.push(_pRoot);
while(!q.empty())
{
Node* pCur = NULL;
pCur = q.front();
cout << pCur->_data << " ";
if (pCur->_pLeft)
{
q.push(pCur->_pLeft);
}
if (pCur->_pRight)
{
q.push(pCur->_pRight);
}
q.pop();
}
}
}
private:
BinaryTreeNode<T>* _pRoot;
};
void FunTest()
{
const char* pstr = "124###35##6";
BinaryTree<char> t(pstr, strlen(pstr), '#');
BinaryTree<char> t1(t);
BinaryTree<char> t2;
t2 = t;
t.LevelOrder();
}