遍历是树结构算法中的重要部分,前面发了有关递归遍历的内容,要知道:递归就是函数调用函数本身,运行起来就是函数嵌套函数,层层嵌套,所以函数调用、参数堆栈都是不小的开销,但是程序简单。然而,非递归即不断地对参数入栈、出栈,省去了函数层层展开、层层调用的开销。虽然参数出入栈次数多了,但是一般都开辟固定的足够大的内存来一次性开辟、重复使用。

目录

一、 先序遍历(非递归) 

遍历步骤

直接上代码

二、 中序遍历(非递归) 

遍历步骤

直接上代码

三、 后序遍历(非递归) 

遍历步骤

直接上代码


一、 先序遍历(非递归) 

遍历步骤

先序遍历的最终访问次序是:根 - 左 - 右 ,具体步骤如下:

1. 设有一棵如下结构的树,并申请一个栈stack,用于存放树结点;

        

java 二叉树的前序遍历非递归 二叉树遍历 非递归 java_jvm

2. 将根节点'1'(如果有的话)入栈; 

        

java 二叉树的前序遍历非递归 二叉树遍历 非递归 java_算法_02

注:入栈时 先右后左

   

while(stack不为空){
               从栈中弹出一个栈顶元素root; 
               访问该结点root;(本例中将此添加到res数组中)
              if (root结点有右儿子)
                   将右儿子结点入栈; 
               if (root结点有左儿子)
                   将左儿子结点入栈;
         }

         

java 二叉树的前序遍历非递归 二叉树遍历 非递归 java_算法_03

         

java 二叉树的前序遍历非递归 二叉树遍历 非递归 java_算法_04

        

java 二叉树的前序遍历非递归 二叉树遍历 非递归 java_b树_05

        

java 二叉树的前序遍历非递归 二叉树遍历 非递归 java_b树_06

         

java 二叉树的前序遍历非递归 二叉树遍历 非递归 java_java_07

        

java 二叉树的前序遍历非递归 二叉树遍历 非递归 java_java_08

         stack栈为空,循环结束,先序遍历完毕!

 直接上代码

// 非递归先序遍历:	
public  void PreOrderTraversalNoRecursive(TreeNode root){
    	if (root != null) {
    		Stack<TreeNode> stack = new Stack<>();
    		stack.add(root);	
    		while(!stack.isEmpty()) {
    		    root = stack.pop();
        		Vist(root);
        		if(root.Rchild != null) {
    			stack.push(root.Rchild);
    			}
        		if(root.Lchild != null) {
        		 stack.push(root.Lchild);
    			}
    		}
        }
    }

二、 中序遍历(非递归) 

遍历步骤

中序遍历的最终访问次序是:左 - 根 - 右 ,具体步骤如下:

1. 设有一棵如下结构的树,并申请一个栈stack,用于存放树结点;

 2. 以下操作为一个循环,

while(stack不为空 ){
               if (当前结点head不为空) :
                    head结点入栈; head = head.left;
              else:
                   head = 栈顶出栈; 
                   访问该结点head;(本例中将此添加到res数组中)
                   head = head.right;
         }

         

java 二叉树的前序遍历非递归 二叉树遍历 非递归 java_jvm_09

        

java 二叉树的前序遍历非递归 二叉树遍历 非递归 java_算法_10

        

java 二叉树的前序遍历非递归 二叉树遍历 非递归 java_b树_11

        

java 二叉树的前序遍历非递归 二叉树遍历 非递归 java_java 二叉树的前序遍历非递归_12

        

java 二叉树的前序遍历非递归 二叉树遍历 非递归 java_jvm_13

         stack1栈为空,循环结束,中序遍历完毕!

 直接上代码

// 非递归中序遍历:     
public  void InOrderTraversalNoRecursive(TreeNode head){
    	if (head != null) {
    		Stack<TreeNode> stack = new Stack<>();
    		while(!stack.isEmpty() || head!=null) {
    			if(head != null) {
    				stack.push(head);
    				head = head.Lchild;
    			}else {
    				head = stack.pop();
    				Vist(head);
    				head = head.Rchild;
    			}
    		}
        }
 }

三、 后序遍历(非递归) 

遍历步骤

后序遍历的最终访问次序是:左 - 右 - 根 ,具体步骤如下:

1. 设有一棵如下结构的树,并申请两个栈s1用于临时存放树结点、s2_res用于存放最终结点序列;

2. 将根节点'1'(如果有的话)入栈; 

        

java 二叉树的前序遍历非递归 二叉树遍历 非递归 java_jvm_14

注:s1入栈时 先左后右

        while(stack不为空) {
              从栈中弹出一个栈顶元素root; 
              访问该结点root;(本例中将此压入到s2_res栈中)

              if (root结点有左儿子)
                  将左儿子结点入栈;

              if (root结点有右儿子)
                  将右儿子结点入栈; 
        }


java 二叉树的前序遍历非递归 二叉树遍历 非递归 java_算法_15

        

java 二叉树的前序遍历非递归 二叉树遍历 非递归 java_java 二叉树的前序遍历非递归_16

        

java 二叉树的前序遍历非递归 二叉树遍历 非递归 java_java_17

        

java 二叉树的前序遍历非递归 二叉树遍历 非递归 java_jvm_18

        

java 二叉树的前序遍历非递归 二叉树遍历 非递归 java_b树_19

        

java 二叉树的前序遍历非递归 二叉树遍历 非递归 java_java_20

         最后将s2所有结点出栈:4 ,5 ,2 ,6 ,7 ,3 ,1 ; 即为后序遍历序列。

直接上代码

// 非递归后序遍历:
public  void PostOrderTraversalNoRecursive(TreeNode root){
    	if (root != null) {
    		Stack<TreeNode> s1 = new Stack<>();// 操作栈
    		Stack<TreeNode> s2 = new Stack<>();// 收集栈
    		s1.add(root);	
    		while(!s1.isEmpty()) {
    			root = s1.pop();
    			s2.push(root);
        		if(root.Lchild != null) {
        			s1.push(root.Lchild);
    			}
        		if(root.Rchild != null) {
    				s1.push(root.Rchild);
    			}
    		}
    		while(!s2.isEmpty()) {
        		Vist(s2.pop());
    		}
        }

    }