二叉樹的前序,中序,後序,層次遍歷(遞迴與非遞迴方式)
阿新 • • 發佈:2018-12-21
以前在學校學過二叉樹的遍歷,工作後基本上沒用到,現在整理下這幾種排序演算法:
1.java的測試方法:
package leetcode.TestList; /** * @author zhangyu * @version V1.0 * @ClassName: TreeNode * @Description: TOTO * @date 2018/12/6 21:32 **/ public class TreeNode { public int val; public TreeNode left; public TreeNode right; public TreeNode(int x) { val = x; } }
2.各種遍歷的方法:
package leetcode; import leetcode.TestList.TreeNode; import java.util.Queue; import java.util.Stack; import java.util.concurrent.ConcurrentLinkedQueue; /** * @author zhangyu * @version V1.0 * @ClassName: Traverse * @Description: TOTO * @date 2018/12/14 9:53 **/ public class Traverse { // 1.前序遞迴遍歷 public void preOrderTraverse1(TreeNode root) { if (root != null) { System.out.println(root.val); preOrderTraverse1(root.left); preOrderTraverse1(root.right); } } // 1.前序非遞迴遍歷 public void preOrderTraverse2(TreeNode root) { // 如果樹為空,直接退出 if (root == null) { return; } // 如果不是新增到棧中 Stack<TreeNode> stack = new Stack<>(); // 如果棧一直不為空就一直迴圈 while (!stack.isEmpty()) { // 定義一個變數接收棧中元素 TreeNode p = stack.pop(); // 如果棧頂不為空,直接輸出 System.out.println(p.val); // 如果左子樹不為空,直接儲存到棧中 if (p.left != null) { stack.push(p.left); } // 如果右子樹不為空,直接儲存到棧中 if (p.right != null) { stack.push(p.right); } } } // 2.中序遞迴遍歷 public void inOrderTraverse(TreeNode root) { if (root != null) { inOrderTraverse(root.left); System.out.println(root.val); inOrderTraverse(root.right); } } // 2.中序非遞迴遍歷 public void inOrderTraverse2(TreeNode root) { // 如果樹為空,直接退出 if (root == null) { return; } // 如果不是新增到棧中 Stack<TreeNode> stack = new Stack<>(); // 如果棧一直不為空就一直迴圈 while (!stack.isEmpty()) { // 定義一個變數接收棧中元素 TreeNode p = stack.pop(); // 如果左子樹不為空,直接儲存到棧中 if (p.left != null) { stack.push(p.left); } // 如果棧頂不為空,直接輸出 System.out.println(p.val); // 如果右子樹不為空,直接儲存到棧中 if (p.right != null) { stack.push(p.right); } } } // 3.後序遞迴遍歷 public void postOrderTraverse(TreeNode root) { if (root != null) { postOrderTraverse(root.left); postOrderTraverse(root.right); System.out.println(root.val); } } // 3.後序非遞迴遍歷 (弄懂後序排序非遞迴) public void postOrderTraverse2(TreeNode root) { if (root == null) { return; } Stack<TreeNode> s = new Stack<>(); TreeNode cur; TreeNode pre = null; s.push(root); while (!s.isEmpty()) { cur = s.pop(); // 兩種情況列印根節點:1.它的左子樹和右子樹為空;2.前驅節點不為空,且前驅節點是當前節點的左子樹或者右子樹 if ((cur.left == null && cur.right == null) || (pre != null && (pre == cur.left || pre == cur.right))) { System.out.println(cur.val); s.pop(); pre = cur; } else { if (cur.right != null) { s.push(cur.right); } if (cur.left != null) { s.push(cur.left); } } } } // 4.層次遍歷非遞迴 (層次遍歷把棧換成佇列) public void levelTraverse(TreeNode root) { if (root != null) { return; } Queue<TreeNode> queue = new ConcurrentLinkedQueue<>(); queue.add(root); while (!queue.isEmpty()) { TreeNode p = queue.poll(); System.out.println(p.val); if (p.left != null) { queue.add(p.left); } if (p.right != null) { queue.add(p.right); } } } }