数据结构与算法面试复习(一):二叉树遍历问题

基本的二叉树遍历分为中序,后序和前序遍历。对他们的遍历又有递归和非递归两种方式。本文主要会涉及两种方式的二叉树遍历,会详细阐述二叉树的非递归遍历方式。

二叉树递归遍历方式

这种方式比较简单,下面是实现的代码: 结点类: TreeNode.java

private class  TreeNode{  
        private String value=null;  
        private TreeNode left=null;  
        private TreeNode right=null;  
          
        public TreeNode(){}  
          
        /** 
         * @param value 数据 
         */  
        public TreeNode(String value){    
            this.value=value;  
            this.left=null;  
            this.right=null;  
        }  
    }  

二叉树前序递归遍历方式:

public void preOrder(TreeNode node){  
        if(subTree!=null){  
            System.out.println(node.value + " ");  
            preOrder(subTree.left);  
            preOrder(subTree.right);  
        }  
    }  

后序和中序遍历就是把输出语句分别放到第五行和第4行,没什么说的。

二叉树非递归遍历

这是重头戏,比较难的。其中后序遍历二叉树的非递归算法最为复杂。下面详细介绍:

前序遍历:

先贴出代码:

public void PreOrderWithoutRec(TreeNode head){  
        System.out.println("前序遍歷的非遞歸實現:");
        if (head != null) {
        	Stack<TreeNode> stack = new Stack<>();
        	stack.add(head);
        	while (!stack.isEmpty()) {
        		head = stack.pop();
        		System.out.println(head.value + " ");
        		if (head.right != null) {
        			stack.push(head.righ);
        		}
        		if (head.left != null) {
        			stack.push(head.left);
        		}
        	}
        }
        System.out.println();
    }  

思路: 1)申请一个新的栈, 记为stack,然后将头结点压入stack中。 2)从stack中取出栈顶结点,打印,先将其右孩子推入栈中,再将左孩子压入栈中。 3)不断重复2)直到stack为空为止。

中序遍历

先提出代码:

public void nonRecInOrder(TreeNode head){  
        System.out.println("中序遍歷");
        if (head != null) {
        	Stack<TreeNode> stack = new Stack<>();
        	while (!stack.isEmpty() || head != null) {
        		if (head != null) {
        			stack.add(head);
        			head = head.left;
        		} else {
        			head = stack.pop();
        			System.out.println(head.value + " ");
        			head = head.right;
        		}
        	}
        }
    }  

思路: 1)申请一个新的栈stack,初始是将头节点压入stack中 2)依次把head的左节点复制给head。重复,直到head为空。 3)从stack中取出结点并打印,并让head=head.right,重复2) 就是无论如何都要现打印左子树。

后序遍历

这种比较复杂,我用两个Stack来实现: 贴出代码:

public void PostOrderWithoutRec(TreeNode head){  
       System.out.println("後序遍歷方法1");
       if (head != null) {
    	   Stack<TreeNode> s1 = new Stack<>();
    	   Stack<TreeNode> s2 = new Stack<>();
    	   s1.push(head);
    	   while (!s1.isEmpty()) {
    		   TreeNode node = s1.pop();
    		   s2.push(node);
    		   if (node.left != null) 
    			   s1.push(node.left);
    		   if (node.right != null) 
    			   s1.push(node.right);
    	   }
    	   while (!s2.isEmpty()) {
    		   System.out.println(s2.pop().value + " ");
    	   }
       }
    }  

思路: 1)申请两个栈s1,s2.先将head压入s1. 2)从s1弹出结点,放入head中并将左右孩子分别压入栈中。 3)对于s2.在整个过程中,将每一个从s1弹出的结点都放进s2中。 4)不断重复2)3)直到s1为空。 5)从s2弹出结点并打印 为什么是这样做:我们知道,没棵子树的头节点都是最先从s1中弹出,然后把该结点的孩子结点按照从左到右的顺序压入s1,那么从s1弹出的顺序就是现右再左,所以从s1中弹出的顺序就是中,右,左。s2重新输出就是s1弹出顺序的逆序。所以s2从栈顶到栈底的顺序就是左,右,中。

    原文作者:dfgrgegsezgzs
    原文地址: https://blog.csdn.net/dfgrgegsezgzs/article/details/66971839
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞