java二叉树的遍历

二叉树遍历

二叉树遍历:按照某种规则对二叉树中的每个节点进行操作(例如:打印节点中的内容||给节点中的值域+1),并且每个节点只遍历一次。

*如果要遍历一棵二叉树,实际只需要将根节点+根的左子树+根的右子树

  1. NLR:前序遍历(Preorder Teaversal也叫先序遍历)——访问根结点的操作发生在遍历其左右子树之前。
    根节点——》根的左子树——》根的右子树
  2. LNR:中序遍历(Inorder Traversal)——访问根结点的操作发生在遍历其左右子树之中(间)。
    根的左子树——》根节点——》根的右子树
  3. LRN:后序遍历(Postorder Traversal)——访问根结点的操作发生在遍历其左右子树之后。
    根的左子树——》根的右子树——》根节点
    由于被访问的结点必是某子树的根,所以N(Node)、L(Left subtree)和R(Right subtree)又可解释为根、根的左子树和根的右子树。
前序遍历:根节点—> 根的左子树 —>根的右子树

在这里插入图片描述

//递归
public void preOrder(BTNode root){
  if(null!=root){
     System.out.print(root.val+" ");
     preOrder(root.left);
     preOrder(root.right);
  }
}

非递归遍历:

(1)非递归前序遍历需要借助栈,利用栈先进后出的特性
方法:

  1. 如果是空树,直接返回
  2. 如果非空
    ++将根节点入栈
    ++(1)取栈顶元素——cur peek();
    ++(2)遍历该元素
    ++(3)删除栈顶元素
    ++(4)如果cur的右子树存在,将右子树入栈
    ++(5)如果cur的左子树存在,将左子树入栈
    ++(6)重复1到5的操作,直至stack为空,遍历完成

(2)根据前序遍历的规则:根 左 右
方法:

  1. 如果是空树,则返回空
  2. 如果非空
    ++将根节点入栈
    ++(1)遍历栈顶cur元素
    ++(2)弹出cur
    ++(3)如果cur有右子树时,保持右子树
    ++(4)顺着cur的左侧的路径一直往下遍历
    ++(5)重复1到4,直至stack为空,遍历完成
//非递归
public void preOrderNor1(){
   if(null==root){
      return ;
   }
   Stack<BTNode> s=new Stack<>();
   s.push(root);
   while(!s.empty()){
      BTNode cur=s.peek();
      System.out.print(cur.val+" ");
      s.pop();
      
      if(null!=cur.right){
         s.push(cur.right);
      }
      if(null!=cur.left){
         s.push(cur.left);
      }
   }
   System.out.println();
}


public void preOrderNor2(){
   if(null==root){
      return ;
   }
   Stack<BTNode> s=new Stack<>();
   s.push(root);
   while(!s.empty()){
      BTNode cur=s.peek();
      s.pop();
      while(null!=cur){
         //顺着cur左侧的路径一直往下遍历,并保存所经路径中的所有右子树
         System.out.print(cur.val+" ");
         if(null!=cur.right){
            s.push(cur.right);
         }
         cur=cur.left;
      }
   }
}
中序遍历:根的左子树 —>根节点—> 根的右子树

在这里插入图片描述

//递归
public void inOrder(BTNode root){
  if(null!=root){
     inOrder(root.left);
     System.out.print(root.val+" "); 
     inOrder(root.right);
  }
}

非递归遍历

非递归中序遍历:

  1. 如果是空树,则返回空。
  2. 如果非空
    ++(1)先找以cur为根的二叉树中最左侧的节点,并把途中所有cur压入栈中
    ++(2)当cur为空时,认为cur对应的树已经遍历。(获取当前栈顶元素,因为cur左子树为空,则认为cur的左子树已经遍历结束)
    ++(3)遍历当前根节点cur
    ++(4)遍历cur的右子树:null(不处理),若不为空则把右子树当成一个新的二叉树进行遍历(重复1到4,直至stack为空)
//非递归
public void inOrderNor(){
    if(null==root){
        return;
    }
    BTNode cur=root;
    Stack<BTNode> s=new Stack<>();
    while(null!=cur||!s.empty()){
	    while(null!=cur){
	       s.push(cur);
	       cur=cur.left;
	    }
	    cur=s.peek();
	    System.out.print(cur.val+" ");
	    s.pop();
	    cur=cur.right;
    }
}
后序遍历:根的左子树 —> 根的右子树—>根节点

在这里插入图片描述

//递归
public void postOrder(BTNode root){
  if(null!=root){
     postOrder(root.left);
     postOrder(root.right);
     System.out.print(root.val+" ");  
  }
}

非递归遍历:

非递归后序遍历:

  1. 如果是空树,则返回null;
  2. 如果非空
    ++(1)找以cur为根的二叉树最左侧的节点,并保存途中所有根节点。
    ++(2)获取栈顶元素peek,拿着栈顶元素去寻找它的右子树
    ++(3)遍历栈顶元素的右子树,如果右子树为空,则弹出栈顶元素cur,并遍历cur;如果右子树=prev则表示右子树已经被遍历过了,也要弹出栈顶元素cur,并遍历cur;如果右子树不为空且没有遍历过,则把右子树当初一个新二叉树重复1到3进行遍历。
    ++(4)prev标注上一次遍历过的节点
//非递归
public void inOrderNor(){
    Stack <BTNode> s=new Stack<>();
    BTNode prev=null;
    if(null==root){
        return;
    }
    BTNode cur=root;
    while(null!=cur||!s.empty()){
          while(null!=cur){
              s.push(cur);
              cur=cur.right;
          }
          BTNode top=s.peek();
          if(null==top.rigth||top.rigth==prev){
              System.out.println(top.val+' ');
              prev=top;
              s.pop();
          }
          else {
              cur=top.rigth;
          }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值