Leetcode036--二叉树遍历的几种方式

来源:互联网 发布:stcisp软件下载 编辑:程序博客网 时间:2024/06/07 06:03

一、原题



Given a binary tree, return the inorder traversal of its nodes values. 


一、中文



二叉树的前序、中序、后序三种遍历方式的总结



三、举例



前序:根-左-右

中序:左-根-右

后序:左-右-根


四、思路



 
每一种遍历方式都有两种方式,一种是递归,一种是非递归的方式,递归很简单,下面主要是非递归的方式

(1)前序

首先建立一个栈,根据前序遍历访问的顺序,优先访问根结点,然后再分别访问左孩子和右孩子。即对于任一结点,其可看做是根结点,因此可以直接访问(打印或者是存入list)。访问完之后再访问他的左子树,当访问到没有左子树的时候,访问其右子树。

     1)访问结点P,并将结点P入栈;

     2)判断结点P的左孩子是否为空,若为空,则取栈顶结点并进行出栈操作,并将栈顶结点的右孩子置为当前的结点P,循环至1);若不为空,则将P的左孩子置为当前的结点P;

     3)直到P为NULL并且栈为空,则遍历结束。



(2)中序

根据中序遍历的顺序,对于任一结点,优先访问其左孩子,而左孩子结点又可以看做一根结点,然后继续访问其左孩子结点,直到遇到左孩子结点为空的结点才进行访问,然后按相同的规则访问其右子树。

  1)若其左孩子不为空,则将P入栈并将P的左孩子置为当前的P,然后对当前结点P再进行相同的处理;

  2)若其左孩子为空,则取栈顶元素并进行出栈操作,访问该栈顶结点,然后将当前的P置为栈顶结点的右孩子;

  3)直到P为NULL并且栈为空则遍历结束


(3)后序

要保证根结点在左孩子和右孩子访问之后才能访问,因此对于任一结点P,先将其入栈。如果P不存在左孩子和右孩子,则可以直接访问它;或者P存在左孩子或者右孩子,但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点。若非上述两种情况,则将P的右孩子和左孩子依次入栈,这样就保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问,左孩子和右孩子都在根结点前面被访问。




五、程序

 

package code;import java.util.Stack;class TreeNode{int val;TreeNode left;TreeNode right;TreeNode(int x){val = x;}}public class LeetCode49{public static void main(String args[]){TreeNode n1 = new TreeNode(1);TreeNode n2 = new TreeNode(2);TreeNode n3 = new TreeNode(3);TreeNode n4 = new TreeNode(4);TreeNode n5 = new TreeNode(5);n1.left = n2;n1.right = n3;n2.left = n4;n2.right = n5;System.out.print("递归的方式中序:");midOrder1(n1);System.out.println();System.out.print("遍历的方式中序:");midOrder2(n1);System.out.println();System.out.print("遍历的方式前序:");preOrder2(n1);System.out.println();System.out.print("遍历的方式后序:");postOrder2(n1);}//第一种使用递归的方式public static void midOrder1(TreeNode root) {if(root != null){midOrder1(root.left);System.out.print(root.val+" ");midOrder1(root.right);}}//第二种使用普通遍历的方式进行中序遍历public static void midOrder2(TreeNode root) {Stack<TreeNode> s = new Stack<TreeNode>();TreeNode p = root;while(p != null || !s.isEmpty()){while(p != null){s.push(p);p = p.left;}if(!s.isEmpty()){p = s.peek();System.out.print(p.val+" ");s.pop();p = p.right;}}}//使用普通的方式进行前序遍历public static void preOrder2(TreeNode root){Stack<TreeNode> s = new Stack<TreeNode>();TreeNode p = root;while(p != null || !s.isEmpty()){while(p != null){System.out.print(p.val+" ");s.push(p);p = p.left;}if(!s.isEmpty()){p = s.peek();s.pop();p = p.right;}}}//使用遍历的方式来进行后序遍历public static void postOrder2(TreeNode root){Stack<TreeNode> s = new Stack<TreeNode>();TreeNode curr = root;//访问的当前结点TreeNode pre = null;//访问的前一个结点s.push(root);while(!s.isEmpty()){curr = s.peek();if((curr.left == null && curr.right == null)||(pre != null)&&(pre == curr.left || pre == curr.right)){System.out.print(curr.val+" ");s.pop();pre = curr;} else {if(curr.right != null){s.push(curr.right);}if(curr.left != null){s.push(curr.left);}}}}}

--------------------------------------output----------------------------------------

递归的方式中序:4 2 5 1 3 遍历的方式中序:4 2 5 1 3 遍历的方式前序:1 2 4 5 3 遍历的方式后序:4 5 2 3 1 





尊重作者,尊重原创,参考文章:

http://www.cnblogs.com/dolphin0520/archive/2011/08/25/2153720.html
http://blog.csdn.net/derrantcm/article/details/47310553



1 0
原创粉丝点击