1.二叉树遍历—递归实现
- 先序遍历—递归实现
void PreOrder()//先序遍历 根-->左子树-->右子树
{
cout<<"PreOrder: ";
_PreOrder(_pRoot);
cout<<endl;
}
- 中序遍历—递归实现
void InOrder()//中序遍历 左子数--》根--》右子树
{
cout<<"InOrder: ";
_InOrder(_pRoot);
cout<<endl;
}
- 后序遍历递归实现
void PostOrder()//后序遍历 左子树--》右子树--》根
{
cout<<"PostOrder: ";
_PostOrder(_pRoot);
cout<<endl;
}
- 层序遍历
void LevelOrder()//层序遍历
{
cout<<"LevelOrder: ";
_LevelOrder(_pRoot);
cout<<endl;
}
void _LevelOrder(Node* pRoot)//层序遍历
{
if(pRoot!=NULL)
{
queue<Node*> q;
q.push(pRoot);
Node*pCur = NULL;
while(!q.empty())
{
pCur = q.front();
cout<<pCur->_data<<" ";
if(pCur->_pLeft)
q.push(pCur->_pLeft);
if(pCur->_pRight)
q.push(pCur->_pRight);
q.pop();
}
}
}
2.二叉树遍历—非递归实现
先序遍历—非递归实现(三种实现方法)
- 实先序遍历现1:访问子树时用栈保存数据,再左右子树存在的情况下,先保存左子树,再保存右子树
void PreOrder_Nor()//先序遍历--循环
{
cout<<"PreOrder_Nor: ";
_PreOrder_Nor(_pRoot);
cout<<endl;
}
void _PreOrder_Nor(Node* pRoot)//前序遍历--循环--实现1(栈中保存的是根)
{
if(pRoot==NULL)
return;
stack<Node*> s;
s.push(pRoot);
while(!s.empty())
{
Node* pCur = s.top();
cout<<pCur->_data<<" ";
s.pop();//访问完后必须立即出栈,因为栈是先进后出的,所以不能再右左孩子入栈之后再出栈
if(pCur->_pRight != NULL)
s.push(pCur->_pRight);
if(pCur->_pLeft != NULL)
s.push(pCur->_pLeft);
}
}
2.先序遍历实现2:
void PreOrder_Nor1()//先序遍历--循环
{
cout<<"PreOrder_Nor: ";
_PreOrder_Nor1(_pRoot);
cout<<endl;
void _PreOrder_Nor1(Node* pRoot)//先序遍历--循环--实现2(先将左子树全部访问并入栈,再依次出栈访问右子树)
{
if(pRoot==NULL)
return;
stack<Node*> s;
Node* pCur = pRoot;
Node* pRev = NULL;
while(pCur!=NULL || !s.empty())
{
while(pCur!=NULL)
{
s.push(pCur);
cout<<pCur->_data<<" ";
pCur = pCur->_pLeft;
}
pCur = s.top();
if(pCur->_pRight==NULL || pRev==pCur->_pRight)
{
pRev = pCur;
s.pop();
pCur = NULL;
}
else
{
pCur = pCur->_pRight;
}
}
}
3.先序遍历实现3:先将根入栈入栈并访问,保存右子树,访问左子树
void PreOrder_Nor2()//先序遍历--循环(实现3,先将根入栈入栈并访问,保存右子树,访问左子树)
{
cout<<"PreOrder_Nor: ";
_PreOrder_Nor2(_pRoot);
cout<<endl;
}
void _PreOrder_Nor2(Node* pRoot)//先序遍历--循环--实现2(访问左子树,保存右子树,当左子树都访问完后,再从栈中取右节点访问)
{
if(pRoot==NULL)
return;
stack<Node*> s;
Node* pCur = pRoot;
while(!s.empty() || pCur)
{
while(pCur)
{
cout<<pCur->_data<<" ";
if(pCur->_pRight)
s.push(pCur->_pRight);//保存右节点是为了再访问完根节点和左子树是能够找到右子树,每次保存一个右子树,访问完后立即出栈,为了保存下一个左子树
pCur = pCur->_pLeft;
}
if(!s.empty())
{
pCur = s.top();
s.pop();
}
}
}
- 中序遍历—循环实现
void InOrder_Nor()//中序遍历--循环
{
cout<<"InOrder_Nor: ";
_InOrder_Nor(_pRoot);
cout<<endl;
}
void _InOrder_Nor(Node* pRoot)//中序遍历---循环
{
if(pRoot == NULL)
return;
stack<Node*> s;
Node* pCur = pRoot;
while(pCur!=NULL || !s.empty())
{
while(pCur!=NULL)//找到最左的节点
{
s.push(pCur);
pCur = pCur->_pLeft;
}
pCur = s.top();
cout<<pCur->_data<<" ";
s.pop();
//pCur = pCur->_pRight; //不区分的时候
while(pCur->_pRight == NULL && !s.empty())//当右子树的节点为NULL时,不断出栈
{
pCur = s.top();
cout<<pCur->_data<<" ";
s.pop();
}
pCur = pCur->_pRight;
}
}
- 后序遍历—循环实现
void PostOrder_Nor()//后序遍历--循环
{
cout<<"PostOrder_Nor: ";
_PostOrder_Nor(_pRoot);
cout<<endl;
}
void _PostOrder_Nor(Node* pRoot)//后续遍历---循环
{
if(pRoot==NULL)
return;
stack<Node*> s;
Node* pCur = _pRoot;
Node* pRev = NULL;//标记该节点是否访问过
while(!s.empty() || pCur!=NULL)
{
while(pCur!=NULL)
{
s.push(pCur);
pCur = pCur->_pLeft;
}
pCur = s.top();
if(pCur->_pRight==NULL || pRev==pCur->_pRight)
{
cout<<pCur->_data<<" ";
pRev = pCur;
s.pop();
pCur = NULL;
}
else
{
pCur = pCur->_pRight;
}
}
}