二叉树遍历之中序遍历(递归与非递归)

一、二叉树中序非递归遍历
1、分析:
二叉树中序遍历的顺序是左子树、根、右子树、而二叉树的前序遍历是根、左子树、右子树。二者相差是先打印根还是先打印左孩子的问题,那我们对前序遍历的代码打印的位置稍作调整,能否得到想要的中序遍历呢?与前序遍历一样,我们需要一个辅助栈来存储一路遍历遇到的’ 根 ‘,来帮助我们找到这个‘ 根 ’的右孩子,首先定义并初始化一个栈 ,开始遍历,先将根保存在栈里,然后往左走,让上一个根的左孩子成为新根,直到新根为空,也就是上一个根没有左孩子,这时栈里的相对上面的结点一定是它下面直接挨着的结点的左孩子,弹出栈顶,打印,这是整棵树的最左面结点,因为它没有左孩子,所以也就是相当于已经走到了根结点那一步,接下来应该找它的右,再次进入保存,向左走的过程。然后弹出,打印,找右,右进入保存,向左走 … …
2、图示解释:以下面这棵树为例,首先栈里保存了依次是1,2,4,因为4没有左孩子了,所以弹出栈顶元素4,它是最左,打印4,然后找右,没有右孩子,接着在弹出2,打印2,找右,有右孩子5,保存5,(栈里现在是1,5)5向左走,没有左孩子,接着弹出5,打印5,找右,5没有右孩子,弹出1,打印1,找右,有右孩子3,保存,向左走,没有左孩子,弹出3,打印3,此时栈里已经没有元素,然后向右走,因为没有右孩子,所以成为的新根是空,自然不能保存进栈,元素个数还是0,结束大循环,得到结果,4,2,5,1,3.
在这里插入图片描述
3、代码

void UnRecInTravresal(BinaryTree* pTree)
 {
    
    
     if(pTree == NULL) return;
     //辅助栈
     Stack *pStack = NULL;
     s_Init(&pStack);
 
     //遍历
     while(1)
     {
    
    
         while(pTree)
         {
    
    
             //保存
             s_Push(pStack,pTree);
             //向左走
             pTree = pTree->pLeft;
         }
         if(pStack->nCount == 0) break;
         //弹出
         pTree = s_Pop(pStack);
         //打印(与前序遍历只有打印的位置不同)
         printf("%d ",pTree->nValue);
         // 找右
         pTree = pTree->pRight;
     }
     printf("\n");
 }

二、二叉树的中序递归遍历
左,根,右,左孩子调用函数,然后左孩子的左孩子调用函数,直到左孩子为空,跳回到了上一层函数,也就是最左面的叶子结点,此时打印它,然后找右,它的右调用函数,找左,就又开始重复上面的过程。

 void InorderTravesal(BinaryTree *pTree)
  {
    
    
      if(pTree == NULL) return;
  
      InorderTravesal(pTree->pLeft);
  
      printf("%d ",pTree->nVaule);
  
      InorderTravesal(pTree->pRight);
  
  }

猜你喜欢

转载自blog.csdn.net/scarificed/article/details/112749419