#include<iostream>
#include<queue>
#include<stack>
using namespace std;
template<class T>
struct BinaryTreeNode
{
BinaryTreeNode< T>(const T& x)
:_data( x)
,_left( NULL)
,_right( NULL)
{}
T _data;
BinaryTreeNode<T >* _left;
BinaryTreeNode<T >* _right;
};
template<class T>
class BinaryTree
{
public:
BinaryTree< T>() //构造函数
:_root( NULL)
{}
BinaryTree< T>(const T* a,size_t size)
{
size_t index=0;
_root=_CreateTree( a,index,size );
}
~BinaryTree< T>() //析构函数
{
Clear();
_root= NULL;
cout<< "~BinaryTree<T>()" <<endl; //是为了析构函数的测试
}
BinaryTree< T>(const BinaryTree& bt) //拷贝构造函数
{
_root=_Copy( bt._root);
}
//BinaryTree<T>& operator=(const BinaryTree& bt) //赋值运算符重载
//{
// if(this!=&bt)
// {
// this->Clear();
// _root=_Copy(bt._root);
// }
// cout<<"BinaryTree<T> operator=()"<<endl;
// return *this;
//}
BinaryTree<T >& operator=(BinaryTree< T> bt ) //赋值运算符重载,利用swap()函数
{
swap(_root, bt._root);
return *this ;
}
void PreOrder() //递归——前序遍历(先根遍历),顺序:根,左,右
{
_PreOrder(_root);
cout<<endl;
}
void InOrder() //递归——中序遍历,顺序:左,根,右
{
_InOrder(_root);
cout<<endl;
}
void PostOrder() //递归——后序遍历,顺序:左,右,根
{
_PostOrder(_root);
cout<<endl;
}
void LevelOrder() //递归——层次遍历,顺序:一层一层遍历
{
_LevelOrder(_root);
cout<<endl;
}
void PreOrder_Non_R() //非递归——前序遍历(先跟遍历),顺序:根,左,右
{
_PreOrder_Non_R(_root);
cout<<endl;
}
void InOrder_Non_R() //非递归——中序遍历,顺序:左,根,右
{
_InOrder_Non_R(_root);
cout<<endl;
}
void PostOrder_Non_R() //非递归——后序遍历,顺序:左,右,根
{
_PostOrder_Non_R(_root);
cout<<endl;
}
void Clear()
{
_Clear(_root);
}
int Size() //二叉树节点个数
{
return _Size(_root);
}
int Hight() //二叉树的深度
{
return _Hight(_root);
}
int LeafNum()
{
return _LeafNum(_root);
}
BinaryTreeNode<T >* Find(const T& x)
{
return _Find(_root,x );
}
protected:
BinaryTreeNode<T >* _CreateTree(const T* a,size_t& index,size_t size) //创建数(关键),注意所传参数和内部逻辑
{
BinaryTreeNode<T >* root=NULL;
if((index <size)&&( a[index ]!='#'))
{
root= new BinaryTreeNode <T>(a[index]);
root->_left=_CreateTree( a,++index ,size);
root->_right=_CreateTree( a,++index ,size);
}
return root;
}
void _PreOrder(BinaryTreeNode <T>* root) //前序遍历(递归)内部函数,顺序:根,左,右
{
if(root ==NULL)
return;
cout<< root->_data<<" " ;
_PreOrder( root->_left);
_PreOrder( root->_right);
}
void _InOrder(BinaryTreeNode <T>* root) //中序遍历(递归)的内部函数,顺序:左,根,右
{
if(root ==NULL)
return;
_InOrder( root->_left);
cout<< root->_data<<" " ;
_InOrder( root->_right);
}
void _PostOrder(BinaryTreeNode <T>* root) //后序遍历(递归)的内部函数,顺序:左,右,根
{
if(root ==NULL)
return;
_PostOrder( root->_left);
_PostOrder( root->_right);
cout<< root->_data<<" " ;
}
//void _LevelOrder(BinaryTreeNode<T>* root) //层次遍历的内部函数,顺序:一层一层遍历(不能用递归,要用队列Queue,先进先出)
//{
// queue<BinaryTreeNode<T>*> q; //先创建一个队列,注意创建方法
// q.push(root); //先将根节点压入队列
// while(root)
// {
// cout<<root->_data<<" "; //先访问根节点
// if(!q.empty())
// {
// BinaryTreeNode<T>* cur=q.front(); //获得先入队的节点
// q.pop(); //将其弹出
// q.push(cur->_left); //其左节点入队
// q.push(cur->_right); //其右节点入队
// root=q.front();
// }
// }
//}
void _LevelOrder(BinaryTreeNode <T>* root) //层次遍历的内部函数,顺序:一层一层遍历(不能用递归,要用队列Queue,先进先出)
{
queue<BinaryTreeNode <T>*> q;
if(root )
q.push( root);
while(!q.empty())
{
BinaryTreeNode<T >* front=q.front();
cout<<front->_data<< " ";
q.pop();
if(front->_left)
q.push(front->_left);
if(front->_right)
q.push(front->_right);
}
}
int _Size(BinaryTreeNode <T>* root) //二叉树的节点个数
{
if(root ==NULL)
return 0;
return _Size(root ->_left)+_Size(root->_right)+1; //左节点数+右节点数+当前根节点
}
int _Hight(BinaryTreeNode <T>* root) //二叉树的深度
{
if(root ==NULL)
return 0;
int LeftHight=_Hight(root ->_left);
int RightHight=_Hight(root ->_right);
return (LeftHight>RightHight)?(LeftHight+1):(RightHight+1); //返回左子树高度和右子数高度中的最大值
}
int _LeafNum(BinaryTreeNode <T>* root) //二叉树的叶子节点个数
{
if(root ==NULL)
return 0;
if((root ->_left==NULL)&&( root->_right==NULL )) //根节点的左右节点都为空,则它是叶子节点
return 1;
return _LeafNum(root ->_left)+_LeafNum(root->_right);
}
void _Clear(BinaryTreeNode <T>* root) //析构的内部函数(等同于后序遍历)
{
if(root !=NULL)
{
_Clear( root->_left);
_Clear( root->_right);
delete(root );
}
}
BinaryTreeNode<T >* _Copy(BinaryTreeNode< T>* root ) //等同于前序遍历
{
if(root ==NULL)
return NULL ;
BinaryTreeNode<T >* newRoot;
BinaryTreeNode<T >* cur=root;
if(cur!=NULL )
{
newRoot= new BinaryTreeNode <T>(cur->_data);
newRoot->_left=_Copy(cur->_left);
newRoot->_right=_Copy(cur->_right);
}
return newRoot;
}
void _PreOrder_Non_R(BinaryTreeNode <T>* root) //前序遍历(非递归)内部函数,顺序:根,左,右,利用栈stack
{
stack<BinaryTreeNode <T>*> s;
if(root )
s.push( root);
while(!s.empty())
{
BinaryTreeNode<T >* top=s.top(); //得到栈顶元素
cout<<top->_data<< " "; //访问这个元素
s.pop(); //将栈顶元素弹出
if(top->_right) //由于栈是先入后出,而前序遍历要保证的顺序是根,左,右,
s.push(top->_right); //所以根访问完后,接下来要先压右,再压左,这样才能保证左比右先出来
if(top->_left)
s.push(top->_left);
}
}
void _InOrder_Non_R(BinaryTreeNode <T>* root) //中序遍历(非递归)的内部函数,顺序:左,根,右
{
stack<BinaryTreeNode <T>*> s;
BinaryTreeNode<T >* cur=root;
while(cur||!s.empty())
{
while(cur)
{
s.push(cur);
cur=cur->_left; //压左节点
}
if(!s.empty())
{
BinaryTreeNode<T >* top=s.top(); //取栈顶元素
cout<<top->_data<< " "; //访问栈顶元素
s.pop();
cur=top->_right; //对右节点的遍历
}
}
}
void _PostOrder_Non_R(BinaryTreeNode <T>* root) //后序遍历(非递归)的内部函数,顺序:左,右,根
{
stack<BinaryTreeNode <T>*> s;
BinaryTreeNode<T >* cur=root;
BinaryTreeNode<T >* prevVisited=NULL;
while(cur||!s.empty())
{
while(cur)
{
s.push(cur);
cur=cur->_left;
}
BinaryTreeNode<T >* top=s.top();
if(top->_right==NULL ||top->_right==prevVisited)
{
cout<<top->_data<< " ";
prevVisited=top;
s.pop();
}
else
cur=top->_right;
}
}
BinaryTreeNode<T >* _Find(BinaryTreeNode< T>* root ,const T& x) //递归查找
{
if(root ==NULL)
return NULL ;
if(root ->_data==x)
return root ;
BinaryTreeNode<T >* lRet=_Find(root->_left, x);
if(lRet)
return lRet;
return _Find(root ->_right,x);
}
protected:
BinaryTreeNode<T >* _root;
};
void test()
{
int array[10]={1,2,3,'#' ,'#',4,'#','#',5,6};
//BinaryTree<int> t1;
BinaryTree<int > t2(array,10);
//t2.PreOrder(); //1, 2, 3, 4, 5, 6
//t2.InOrder(); //3, 2, 4, 1, 6, 5
//t2.PostOrder(); //3, 4, 2, 6, 5, 1
//t2.LevelOrder(); //1, 2, 5, 3, 4, 6
//cout<<t2.Size()<<endl;
//cout<<t2.Hight()<<endl;
//cout<<t2.LeafNum()<<endl;
//BinaryTree<int> t3(t2); //拷贝构造函数的测试
//t3.PreOrder();
//t3.InOrder();
//t3.PostOrder();
//t3.LevelOrder();
//cout<<t3.Size()<<endl;
//cout<<t3.Hight()<<endl;
//cout<<t3.LeafNum()<<endl;
//BinaryTree<int> t4; //赋值运算符重载的测试
//t4=t2;
//t4.PreOrder();
//t4.InOrder();
//t4.PostOrder();
//t4.LevelOrder();
//cout<<t4.Size()<<endl;
//cout<<t4.Hight()<<endl;
//cout<<t4.LeafNum()<<endl;
//t2.PreOrder_Non_R();
//t2.InOrder_Non_R();
//t2.PostOrder_Non_R();
BinaryTreeNode<int >* ret=t2.Find(4);
}
int main()
{
test();
system( "pause");
return 0;
}
层次遍历思路:(不用递归,而是利用队列的先进先出原则)
首先,访问二叉树根节点,并将其入队
其次,当队列不为空时,重复以下操作:
1.从队列弹出一个节点
2.将其左右节点压入队列
本文出自 “追寻内心的声音” 博客,转载请与作者联系!