43.递归和非递归俩种方法实现二叉树的前序遍历。
题目来源:
微软等公司数据结构+算法面试100 题V0.1 版
http://topic.youkuaiyun.com/u/20101126/10/b4f12a00-6280-492f-b785-cb6835a63dc9.html
分析:
递归遍历简单明了,不罗嗦,非递归形式可以使用堆栈实现。
//前序遍历 递归方式
void preorder1(BSTreeNode *pNode)
{
if(pNode==NULL)
return;
cout<<pNode->m_value<<" ";
preorder1(pNode->m_pleft);
preorder1(pNode->m_pright);
}
//前序遍历 非递归方式
void preorder2(BSTreeNode *pNode)
{
if(pNode==NULL)
return;
stack<BSTreeNode *> bstStack;
bstStack.push(pNode);
while (!bstStack.empty())
{
BSTreeNode *pNode=bstStack.top();
bstStack.pop();
cout<<pNode->m_value<<" ";
if (pNode->m_pright!=NULL)
bstStack.push(pNode->m_pright);
if (pNode->m_pleft!=NULL)
bstStack.push(pNode->m_pleft);
}
}
前序遍历是典型的尾递归,很好消除,对于后序遍历和中序遍历的实现就稍微复杂一些了,需要附加变量来记录是否访问过。在二叉树结构体中添加 bool m_bvisit;
后序遍历,中序遍历的实现代码。
//后序遍历 递归
void postorder1(BSTreeNode *pNode)
{
if(pNode==NULL)
return;
postorder1(pNode->m_pleft);
postorder1(pNode->m_pright);
cout<<pNode->m_value<<" ";
}
//后序遍历 非递归
void postorder2(BSTreeNode *pNode)
{
if(pNode==NULL)
return;
SetUnvisited(pNode); //将所有节点设置为未访问
stack<BSTreeNode *> bstStack;
bstStack.push(pNode);
while (!bstStack.empty())
{
BSTreeNode *pNode=bstStack.top();
if (pNode->m_pleft!=NULL&&pNode->m_pleft->m_bvisit==false) //存在左子树,并且未访问
bstStack.push(pNode->m_pleft);
else if(pNode->m_pright!=NULL&&pNode->m_pright->m_bvisit==false) //存在右子树,并且未访问
bstStack.push(pNode->m_pright);
else //不存在左右子树,或都已经访问
{
bstStack.pop();
cout<<pNode->m_value<<" ";
pNode->m_bvisit=true;
}
}
}
//中序遍历 递归
void inorder1(BSTreeNode *pNode)
{
if(pNode==NULL)
return;
inorder1(pNode->m_pleft);
cout<<pNode->m_value<<" ";
inorder1(pNode->m_pright);
}
//中序遍历 非递归
void inorder2(BSTreeNode *pNode)
{
if(pNode==NULL)
return;
SetUnvisited(pNode); //将所有节点设置为未访问
stack<BSTreeNode *> bstStack;
bstStack.push(pNode);
while (!bstStack.empty())
{
BSTreeNode *pNode=bstStack.top();
if (pNode->m_pleft!=NULL&&pNode->m_pleft->m_bvisit==false) //存在左子树,并且未访问
bstStack.push(pNode->m_pleft);
else //不存在左子树,或已访问
{
if(pNode->m_bvisit==false) //当前节点未访问
{
cout<<pNode->m_value<<" ";
pNode->m_bvisit=true;
}
if(pNode->m_pright!=NULL&&pNode->m_pright->m_bvisit==false) //存在右子树,并且未访问
bstStack.push(pNode->m_pright);
else //不存在左右子树,或都已经访问
{
bstStack.pop();
}
}
}
}