zoukankan      html  css  js  c++  java
  • 前中后序的非递归实现与理解

    根据自己对于对于遍历的理解

    前序遍历:左右

    中序遍历:左

    后序遍历:左右

    对于前序和中序,可以只改变一些printf的顺序

    所以前中后名称都是针对中间(根)的结点,所以后序遍历是不可以直接移动printf的位置的,因为对于每个结点不能直接出栈,出栈输出的时候需要判断2点

    1.这个节点有没有右子树(如果没有就遍历他的左子树)

    2.这个节点有没有被访问过(如果被访问过说明他的右子树已经遍历完了,可以直接输出)

    1. void NL_Order(BinTree BST)
      {//后序遍历的思路是:左子树走到了尽头之后,往右子树走,先将右子树输出之后再输出左子树,再输出根节点
          BinTree cur = BST, pre = NULL;
          Stack S; S.top = 0;
          while (cur || !IsEmpty(S))
          {
              if (cur)
              {
                  PushStack(S, cur);
                  cur = cur->Lchild;//相比起老师给的范例,少了一层循环,将左子树的都无脑压入
              }
              else
              {
                  GetTop(S, cur);//获取栈顶(要先进行判断)
                  if (cur->Rchild&&cur->Rchild!=pre)    //这是不出栈的,满足了两个条件:①有右结点②没有访问过
                  {
                      cur = cur->Rchild;                //往右边遍历
                  }
                  else
                  {
                      PopStack(S, cur);              //满足出栈条件的
                      cout<<cur->data;
                      pre = cur;                     //记录一下当下访问的这个结点,针对的是右边的叶子,下一轮循环访问栈将是它的根,记录已经输出                     右边,确保下一轮循环它的根节点可以输出(即标记已访问)
                      cur = NULL;//避免把当前当前已经访问过结点入栈(针对第一个if)
                  }
              }
          }
      }


    这是同学的解法,觉得很有新意,也更加便于理解栈和递归之间的关系

    思想:对于每个结点的访问在递归中有三次,第一次是用其来访问左孩子,第二次是用其来访问右孩子,最后一次是跳出前面两个递归之后回归本层递归,所以依据上述先序、中序、后序的理解,区别就在于第几次访问这个栈的结点

    引入一个元素记录访问的次数

  • 相关阅读:
    01-移动端 REM 适配(postcss-pxtorem,lib-flexible的使用)
    19-webpack性能优化集锦
    10-map/WeakMap/WeakSet的使用场景
    03-web worker vue项目实战
    ELFhash
    哈希查找
    Logger之Logger.getLogger(CLass)使用(转载)
    mybatis中多对一查询
    IDEA中无法打开查看log文件解决方案
    Self-Supervised Scene De-occlusion(转载)
  • 原文地址:https://www.cnblogs.com/wengst/p/13205175.html
Copyright © 2011-2022 走看看