二叉树的前序,中序,后序,层序遍历的递归和非递归实现
生活随笔
收集整理的這篇文章主要介紹了
二叉树的前序,中序,后序,层序遍历的递归和非递归实现
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
直接上代碼
import java.util.Stack;public class BinaryTree {//定義一棵二叉樹,包括左子樹、右子樹、該節點的值和構造器public BinaryTree lchild;public BinaryTree rchild;public char data;public BinaryTree(BinaryTree l,BinaryTree r,char data){lchild = l;rchild = r;this.data = data;}//訪問節點的函數public void visit(BinaryTree t){System.out.println(t.data);}/** 遞歸實現二叉樹的遍歷都是分四步* 1.判斷樹如果為空則返回* 2.訪問節點* 3.判斷左子樹如果不為空則遞歸左子樹* 4.判斷右子樹不為空則遞歸右子樹* 前、中、后三個遍歷的區別就是訪問節點這一步分別實在判斷左子樹前,判斷左子樹和右子樹中間,判斷右子樹之后*///遞歸實現前序遍歷public void pre(BinaryTree t){if(t == null)return;visit(t);if(t.lchild != null)pre(t.lchild);if(t.rchild != null)pre(t.rchild);}//遞歸實現中序遍歷public void mid(BinaryTree t){if(t == null)return;if(t.lchild != null)mid(t.lchild);visit(t);if(t.rchild != null)mid(t.rchild);}//遞歸實現后序遍歷public void pos(BinaryTree t){if(t == null)return;if(t.lchild != null)pos(t.lchild);if(t.rchild != null)pos(t.rchild);visit(t);}/*** 非遞歸實現二叉樹的遍歷都是用棧實現*// /*** 非遞歸實現前序遍歷* 注意由于棧先進后出的特點,順序是:出棧并訪問,右子樹不空壓棧,左子樹不空壓棧*/public void pre2(BinaryTree t){Stack<BinaryTree> s = new Stack<>();s.push(t);while(!s.isEmpty()){BinaryTree b = s.pop();visit(b);if(b.rchild != null)s.push(b.rchild);if (b.lchild != null)s.push(b.lchild);}}/*** 非遞歸實現中序遍歷需要一個中間變量p代表當前樹**//public void mid2(BinaryTree t){Stack<BinaryTree> s = new Stack<>();BinaryTree p = t;while(!s.isEmpty() || p!=null){if(p != null){s.push(p);p = p.lchild;}else{p = s.pop();visit(p);p = p.rchild;}}} /*二叉樹的非遞歸后序遍歷和前序遍歷的不同是先判斷一下是不是沒有孩子或者左右孩子已經訪問,然后才可以訪問該節點*/public List<Integer> postorderTraversal(TreeNode root) {List<Integer> res = new ArrayList<>();if (root==null)return res;Stack<TreeNode> stack = new Stack<>();TreeNode last = null;TreeNode cur ;stack.push(root);while (!stack.isEmpty()){cur = stack.peek();if ((cur.left==null&&cur.right==null)||last!=null&&(last==cur.left||last==cur.right)){//沒有孩子或者孩子已經遍歷過 res.add(cur.val);last = cur;stack.pop();}else{if (cur.right!=null)stack.push(cur.right);if (cur.left!=null)stack.push(cur.left);}}return res;} }?還有一種方法:前序遍歷的時候,順序是:根-左-右?,F在只要改成:根-右-左,最后在reverse一下
注意由于stack先進后出,前序遍歷的時候是先壓入右,再壓左,這里是先左后右
public ArrayList<Integer> postorderTraversal(TreeNode root) {if(root==null) return new ArrayList();Stack<TreeNode> stack = new Stack();ArrayList<Integer> res = new ArrayList();stack.push(root);while(!stack.isEmpty()){TreeNode cur = stack.pop();res.add(cur.val);if(cur.left!=null) stack.push(cur.left);if(cur.right!=null) stack.push(cur.right);}Collections.reverse(res);return res;}?層序遍歷:
層序遍歷用BFS
迭代方法:存取節點的結構是queue隊列,常用的實現類是linkedlist,不斷添加節點到隊列后邊
遞歸方法:維護一個二維數組和層數,不同層的數放到不同的數組中
/*迭代方法*/public List<List<Integer>> levelOrder(TreeNode root) {List<List<Integer>> res = new ArrayList<>();if (root==null)return res;Queue<TreeNode> queue = new LinkedList<>();queue.offer(root);while (!queue.isEmpty()){int s = queue.size();List<Integer> cur = new ArrayList<>();for (int i = 0; i < s; i++) {TreeNode temp = queue.poll();cur.add(temp.val);if (temp.left!=null)queue.offer(temp.left);if (temp.right!=null)queue.offer(temp.right);}res.add(cur);}return res;}遞歸方法:
List<List<Integer>> res = new ArrayList<>();public List<List<Integer>> levelOrder(TreeNode root) {helper(root,0);return res;}public void helper(TreeNode root,int c){if (root==null)return;if (res.size()==c)res.add(new ArrayList<>());List<Integer> cur = res.get(c);cur.add(root.val);if (root.left!=null)helper(root.left,c+1);if (root.right!=null)helper(root.right,c+1);}?
轉載于:https://www.cnblogs.com/stAr-1/p/7058262.html
總結
以上是生活随笔為你收集整理的二叉树的前序,中序,后序,层序遍历的递归和非递归实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: :src 三目运算
- 下一篇: 熟悉常用的Linux命令操作