• 二叉树递归和非递归遍历


    1、递归遍历

    // 先序遍历(递归实现)-------------------------------------------------------------
     	  /*
    	  1. Visit the node.
    	  1. Call itself to traverse the node’s left subtree.
          3. Call itself to traverse the node’s right subtree.
    	  4. base case: there is no node
    	  */
       private void preOrder(Node localRoot){
          if(localRoot != null)
             {
             visit(localRoot);       // System.out.print(localRoot.iData + " ");
             preOrder(localRoot.leftChild);
             preOrder(localRoot.rightChild);
             }
          }
    // 中序遍历(递归实现)-------------------------------------------------------------
       private void inOrder(Node localRoot){
          if(localRoot != null)
             {
             inOrder(localRoot.leftChild);
             visit(localRoot);       //System.out.print(localRoot.iData + " ");
             inOrder(localRoot.rightChild);
             }
          }
    // 后序遍历(递归实现)-------------------------------------------------------------
       private void postOrder(Node localRoot){
          if(localRoot != null)
             {
             postOrder(localRoot.leftChild);
             postOrder(localRoot.rightChild);
             visit(localRoot);       //System.out.print(localRoot.iData + " ");
             }
          }
    // -------------------------------------------------------------

    2、非递归遍历

    /*
    总体思想是:因为递归的本质是用栈实现的,所以写出非递归的形式要用到栈。入栈的顺序与访问的顺序相反,如中序遍历访问顺序是left,current,right,所以入栈的顺序相反是right,current,left
    steo0:初始化当前节点current
    step1:初始化栈
    step3:出栈,并访问
    Note:中序遍历和后序遍历需要先判断bPushed为true时访问)
    step2:入栈
    循环结束条件是:栈为空
    */
    
    //算法框架 pushNode是入栈的方式
    public void templet(Node root){
      //special case
      if(root==null)
       return;
       
      //inital current node
      Node current=root;
      
      //initial stack
      Stack s=new Stack();
      pushNode(current,s);
      
      //loop: base case is stack is empty
      while( !s.empty() ){
         //pop
    	 current=s.pop();
    	 
    	 //visit or push
      }//end while  
    }//end templet()
    
    // 先序遍历-深度优先搜索(递归实现)-------------------------------------------------------------
    //current left right  
      //step1:pop current node
    	//step2:visit current node
    	//step3:push current's right child
    	//step4:push current's left child
    	//step5: loop step1-step5
    
    privete void pushPreOrderNode(Node current, Stack s){
       if(current==null)
          return ;
       	if(!s.empty()){
    	   leftChild=current.leftChild;
    	   rightChild=curret.rightChild;
    	     
    	   if(rightChild!=null)    //push rightChild
    	      s.push(rightChild);
    	   if(leftChild!=null)     //push leftChild
    	      s.push(leftChild):
    	   visit(current);        //current always first visit in preOrder  
    	}//end if 
    }//end pushPreOrderNode()
    
    public void preOrder(Node root){
        //special case
    	if(root==null)
    	  return ;
    	
    	//inintial current node
    	Node current=root;
    	//inintial stack
    	Stack s=new Stack();
    	pushPreOrderNode(current,s);
    	
    	//base case:stack is empty
    	while( !s.empty() ){
    	  //pop
    	  current=s.pop();
    	  //push
    	  pushPreOrderNode(current,s);
    	}//end while
    }//end preOrder()
    	
    // 中序遍历(非递归实现)-------------------------------------------------------------
    /*
    left current right
    */
    
    public void inOrder( Node root){
       //special case
       if(root==null)
           return;
    	   
    	Node current=root;
    	//initial stack
    	Stack s=new Stack();
    	pushInOrderNode(current,s);
    	
    	//pop and visit
    	while( !s.empty() ){
    	     current=s.pop();
    		 if(current.bPushed)
    		    visit(current);
    		 else
    		    pushInOrderNode(current,s);
    	}//end while
    }//end postOrder()
    
    private void pushInOrderNode(Node current,Stack s){
        if(current==null)
    	  return;
    	if(!s.empty()){
    	   leftChild=current.leftChild;
    	   rightChild=curret.rightChild;
    	   
    	   if(rightChild!=null){   //push rightChild
    		  s.push(rightChild);
    		  rightChild.bPushed=false;
    	   }//end if
    	   
    	   s.push(current);        //push current
    	   
    	   
    	   
    	   if(leftChild!=null){    //push leftChild
    	   	  s.push(leftChild);
    	      rightChild.bPushed=false;
    	   }//end if
    		  
    	   //set flag, ture present current's left and right has both pushed
    	   current.bPushed=true;
    	   }//end if
    	}//end if
    }//end pushInOrderNode()
    // -------------------------------------------------------------
    
    
    // 后序遍历(递归实现)-------------------------------------------------------------
    /*
    left right current
    step1:初始化栈
    按照step2初始化栈
    step2:入栈
    入栈顺序:current,right,left
    如果current的中左右节点都入栈了,将current标识为true;
    将入栈的左右节点标识初始化为false
    step3:出栈
    出栈节点设置为current,
    如果current标识为ture,访问之;如果为false,做step2步骤
    step4:重复step2&step3
    */
    
    public void postOrder( Node root){
       //special case
       if(root==null)
           return;
    	   
    	Node current=root;
    	
    	//initial stack
    	Stack s=new Stack();
    	pushPostOrderNode(current,s);
    	
    	//pop and visit
    	while( !s.empty() ){
    	     current=s.pop();
    		 if(current.bPushed)
    		    visit(current);
    		 else
    		    pushPostOrderNode(current,s);
    	}//end while
    }//end postOrder()
    
    // 左右子树尚未入栈,则依次将 根节点,右节点,左节点 入栈
    private void  pushPostOrderNode(Node current, Stack s){
        if(current==null)
    	  return;
    	if(!s.empty()){
    	   leftChild=current.leftChild;
    	   rightChild=curret.rightChild;
    	   
    	   s.push(current);        //push current
    	   if(rightChild!=null){   //push rightChild
    		  s.push(rightChild);
    		  rightChild.bPushed=false;
    	   }//end if
    	   if(leftChild!=null){    //push leftChild
    	   	  s.push(leftChild);
    	      rightChild.bPushed=false;
    	   }//end if
    		  
    	   //set flag, ture present current's left and right has both pushed
    	   current.bPushed=true;
    	   }//end if
    	}//end if
    	
    }//end pushPostOrderNode()

    3 深度优先搜索和层次遍历(广度优先搜索)

    // -------------------------------------------------------------
    /*
    二叉树的广度深度优先搜索即先序遍历,用栈实现(非递归实现)
    */
    
    // -------------------------------------------------------------
    /*
    层次搜索,即广度优先搜索
    step1:specail case
    root==null;
    step2:initial current
    current=root;
    step3:initial queue
    step4:remove node in queue, and visit the current node
    step5:add node in queue
    step6:loop step4 and step5
    base case: queue is empty
    */
    
    public void gfs(Noode root){
      //step1:specail case
      if(root==null)
        return ;
      
      //step2:initial current
      Node current=root;
      
      //step3:initial queue
      Queue q=new Queue();
      q.add(current);
      
      //step6:loop step4 and step5
      //base case: queue is empty
      while( !q.empty() ){
        //step4:remove node in queue
    	current=q.remove();
    	visit(current);
    	
    	Node leftChild=current.leftChild;
    	Node rightChild=curret.rightChild;
    	
    	//step5:add node in queue
    	if(leftChild!=null)
    	   q.add(leftChild);
    	if(rightChild!=null)
    	   q.add(rightChild);
      }//end while 
    }//gfs()



  • 相关阅读:
    十个MySQL常用函数
    写给三十岁的自己
    EJS 模板引擎
    发送HTTP请求(GET,POST)
    路由模块化
    原生NodeJS封装Express路由
    Hook简介
    State Hook (useState)
    Effect hooks
    useContext
  • 原文地址:https://www.cnblogs.com/dyllove98/p/3127468.html
Copyright © 2020-2023  润新知