最近在学习数据结构,在这写一下二叉树的前序、后序和中序的递归遍历和非递归遍历算法和实现。
1、二叉树的前序遍历:
1)递归遍历算法和实现:根节点>>左孩子>>右孩子
void preOrder(MyStruct *proot)
{
if (proot != nullptr)
{
cout << proot->Nodedata << " ";
preOrder(proot->pLeft);
preOrder(proot->pRight);
}
}
2)非递归遍历算法和实现:先判断传入节点是否为空,为空则什么都不用做。然后从根节点一直向左孩子访问,并把访问过的节点全部压入stack中,一直到当前的节点的左孩子为空。将栈中第一个节点弹出并指向当前结点(pcurr=pcurr->pright)的右孩子,如果pcurr不为空则访问该节点,并判断pcurr->pleft是否为空,不为空则继续访问左孩子,为空则继续弹出栈中元素,继续以上步骤直到栈为空。
void PreOrder(MyStruct *proot)
{
MyStruct *pcurr = proot;
stack<MyStruct*> mystack1;
if (pcurr == NULL)
{
return;
}
while (!mystack1.empty() || pcurr != NULL)
{
while (pcurr != nullptr)
{
cout << pcurr->Nodedata << " ";
mystack1.push(pcurr);
pcurr = pcurr->pLeft;
}
if (!mystack1.empty())
{
pcurr = mystack1.top();
mystack1.pop();
pcurr = pcurr->pRight;
}
}
}
2、二叉树的中序遍历
1)递归遍历算法和实现:左孩子>>根节点>>右孩子
void midOrder(MyStruct *proot)
{
if (proot != nullptr)
{
midOrder(proot->pLeft);
cout << proot->Nodedata << " ";
midOrder(proot->pRight);
}
}
2)非递归遍历算法和实现:1、先判断传入的节点是否为空,为空则函数什么都不用做。2、然后一直向树的左孩子传递并将其压入栈中。至当前结点的左孩子为空,则访问当前结点,3、并将当前结点(pcurr)从栈中弹出。4、随后将当前结点指向该节点的右孩子,5、如果不为空则压入堆栈,并将该节点指向其左孩子至节点的左孩子为空。6、如果为空则继续弹出栈中的第一个元素并继续以上步骤直至栈为空。
void MidOrder(MyStruct *proot)
{
if (proot == NULL)
{
return;
}
MyStruct *pcurr = proot;
stack<MyStruct* > mystack1;
while (pcurr != NULL || !mystack1.empty())
{
while (pcurr != NULL)
{
mystack1.push(pcurr);
pcurr = pcurr->pLeft;
}
if (!mystack1.empty())
{
pcurr = mystack1.top();
mystack1.pop();
cout << pcurr->Nodedata << " ";
pcurr = pcurr->pRight;
}
}
}
3、二叉树的后序遍历
1)递归遍历算法和实现:左孩子>>右孩子>>根节点
void postOrder(MyStruct *proot)
{
if (proot != nullptr)
{
postOrder(proot->pLeft);
postOrder(proot->pRight);
cout << proot->Nodedata << " ";
}
}
2)非递归遍历算法和实现:1、先判断传入节点是否为空,为空则函数结束。2、将当前结点传入栈中,并判断该节点的左右孩子是否为空,或者是否之前访问过的节点。3、是的话则访问该节点并将当前结点弹出栈4、否的话并且该节点的右孩子是否为空,否的话则压入栈中。5再判断左孩子是否为空,否的话压入栈中。6重复以上步骤知道栈为空。
void PostOrder(MyStruct *proot)
{
MyStruct *pcurr = proot;
MyStruct *pre = proot;
stack<MyStruct*> mystack1;
if (pcurr == NULL)
{
return;
}
mystack1.push(pcurr);
while (!mystack1.empty())
{
pcurr = mystack1.top();
if ((pcurr->pLeft == NULL && pcurr->pRight == NULL) || (pre != NULL && (pre == pcurr->pLeft || pre == pcurr->pRight)))
{
cout << pcurr->Nodedata << " ";
pre = pcurr;
mystack1.pop();
}
else
{
if (pcurr->pRight != NULL)
{
mystack1.push(pcurr->pRight);
}
if (pcurr->pLeft != NULL)
{
mystack1.push(pcurr->pLeft);
}
}
}
}
总结:以上程序在vs2017的环境中用一个3层的二叉树进行验证,由于本人能力有限,以上算法或者实现有错误的或者不当的地方欢迎指出。
参考:http://www.cnblogs.com/dolphin0520/archive/2011/08/25/2153720.html
https://blog.csdn.net/abinge317/article/details/51168757