当前位置:C++技术网 > 资讯 > 数据结构笔记分享:33 如何不用递归实现二叉树的前序/后序/中序遍历?

数据结构笔记分享:33 如何不用递归实现二叉树的前序/后序/中序遍历?

更新时间:2016-01-27 22:43:44浏览次数:1+次

算法思想:三种算法的思想都是让root的Left的Left的Left全都入栈。所以第一个while循环的逻辑,都是相同的。

下面详细分析第2个while循环,这是一个出栈动作,只要栈不为空,就始终要弹出栈顶元素,由于我们之前入栈的都是Left节点,所以每次在出栈的时候,我们都要考虑Right节点是否存在。因为前序/后序/中序遍历顺序的不同,所以在具体的实现上有略为区别。

1)前序遍历

这个是最简单的。

前序遍历是root->root.Left->root.Right的顺序。

因为在第一个while循环中,每次进栈的都可以认为是一个root,所以我们直接打印,然后root.Right和root.Left先后进栈,那么出栈的时候,就能确保先左后右的顺序。

static void PreOrder(BinNode root)
{
  Stack stack = new Stack();
  BinNode temp = root;
  //入栈
  while (temp != null)
   {
      Console.WriteLine(temp.Element);
      if (temp.Right != null)
          stack.Push(temp.Right);
      temp = temp.Left;
   }
  //出栈,当然也有入栈
  while (stack.Count > 0)
   {
      temp = (BinNode)stack.Pop();
      Console.WriteLine(temp.Element);
      while (temp != null)
      {
          if (temp.Right != null)
               stack.Push(temp.Right);
          temp = temp.Left;
      }
   }
}

后序遍历比较麻烦,需要记录上一个访问的节点,然后在本次循环中判断当前节点的Right或Left是否为上个节点,当前节点的Right为null表示没有右节点。

static void PostOrder(BinNode root)
{
  Stack stack = new Stack();
  BinNode temp = root;
  //入栈
  while (temp != null)
   {
      if (temp != null)
          stack.Push(temp);
      temp = temp.Left;
   }
  //出栈,当然也有入栈
  while (stack.Count > 0)
   {
      BinNode lastvisit = temp;
       temp = (BinNode)stack.Pop();
      if (temp.Right == null || temp.Right == lastvisit)
      {
          Console.WriteLine(temp.Element);
      }
      else if (temp.Left == lastvisit)
      {
          stack.Push(temp);
          temp = temp.Right;
          stack.Push(temp);
          while (temp != null)
          {
               if (temp.Left != null)
                   stack.Push(temp.Left);
               temp = temp.Left;
          }
      }
   }
}

中序遍历,类似于前序遍历

static void InOrder(BinNode root)
{
  Stack stack = new Stack();
  BinNode temp = root;
  //入栈
  while (temp != null)
   {
      if (temp != null)
          stack.Push(temp);
      temp = temp.Left;
   }
  //出栈,当然也有入栈
   while(stack.Count > 0)
   {
      temp = (BinNode)stack.Pop();
      Console.WriteLine(temp.Element);
      if (temp.Right != null)
      {
          temp = temp.Right;
          stack.Push(temp);
          while (temp != null)
          {
               if (temp.Left != null)
                   stack.Push(temp.Left);
               temp = temp.Left;
          }
      }
   }
}