這幾天在復習關於樹的各種算法,做了一些題,也搜索了網上各種算法,現在來總結一下樹的各種常見算法。
本文涵蓋:
二叉樹先中后序遍歷(遞歸&非遞歸)算法
層次遍歷(正序&逆序&鋸齒形)非遞歸算法
二叉樹深度算法
結點總數算法
1.二叉樹先序非遞歸遍歷
//先序非遞歸遍歷 public ArrayList<Integer> preorderTraversal2(TreeNode root) { Stack<TreeNode> stack = new Stack<TreeNode>(); stack.push(root); while(!stack.isEmpty()){ TreeNode newtree = stack.pop(); list.add(newtree.val); if(newtree.right!=null) stack.push(newtree.right); if(newtree.left!=null) stack.push(newtree.left); } return list; }
2.先序遞歸遍歷
ArrayList<Integer> list =new ArrayList<Integer>(); //先序遞歸遍歷 public ArrayList<Integer> preorderTraversal(TreeNode root) { if(root!=null){ list.add(root.val); preorderTraversal(root.left); preorderTraversal(root.right); } return list; }
3.二叉樹中序非遞歸遍歷
public ArrayList<Integer> inorderTraversal2(TreeNode root){ Stack<TreeNode> stack = new Stack<TreeNode>(); while(!stack.isEmpty()||root!=null){ while(root!=null){ stack.push(root); root = root.left; } root = stack.pop(); list.add(root.val); root = root.right; } return list; }
4.中序遞歸遍歷
//遞歸中序遍歷二叉樹 public ArrayList<Integer> inorderTraversal(TreeNode root) { if(root!=null){ inorderTraversal(root.left); list.add(root.val); inorderTraversal(root.right); } return list; }
5.二叉樹后序非遞歸遍歷
//非遞歸后序遍歷 public void postorderTraversa2(TreeNode root) { Stack<TreeNode> s = new Stack<TreeNode>(); TreeNode cur=null; //當前結點 TreeNode pre=null; //前一次訪問的結點 s.push(root); while(!s.empty()) { cur=s.peek(); if((cur.left==null&&cur.right==null)|| (pre!=null&&(pre==cur.left||pre==cur.right))) { list.add(cur.val); //如果當前結點沒有孩子結點或者孩子節點都已被訪問過 s.pop(); pre=cur; } else { if(cur.right!=null) s.push(cur.right); if(cur.left!=null) s.push(cur.left); } } }
6.遞歸后序遍歷
//遞歸后序遍歷 public ArrayList<Integer> postorderTraversal(TreeNode root) { if(root!=null){ postorderTraversal(root.left); postorderTraversal(root.right); list.add(root.val); } return list; }
7.層次遍歷
//層次遍歷 public ArrayList<ArrayList<Integer>> levelOrder(TreeNode root) { ArrayList<ArrayList<Integer>> list = new ArrayList<ArrayList<Integer>>(); Queue<TreeNode> q = new LinkedList<TreeNode>(); if(root!=null) q.add(root); while(!q.isEmpty()){ ArrayList<TreeNode> inlist = new ArrayList<TreeNode>(); ArrayList<Integer> result = new ArrayList<Integer>(); while(!q.isEmpty()){ inlist.add(q.poll()); } for(int i=0;i<inlist.size();i++){ result.add(inlist.get(i).val); if(inlist.get(i).left!=null) q.offer(inlist.get(i).left); if(inlist.get(i).right!=null) q.offer(inlist.get(i).right); } list.add(result); } return list; }
8.鋸齒形層次遍歷
//鋸齒形層次遍歷(先從左往右,下一層再從右往左,層與層之間交替進行) public ArrayList<ArrayList<Integer>> zigzagLevelOrder(TreeNode root) { // write your code here ArrayList<ArrayList<Integer>> arr = new ArrayList<ArrayList<Integer>>(); boolean direction = true; Stack<TreeNode> stack = new Stack<TreeNode>(); if(root!=null) stack.push(root); while(!stack.isEmpty()){ ArrayList<Integer> result = new ArrayList<Integer>(); List<TreeNode> list = new ArrayList<TreeNode>(); while(!stack.isEmpty()){ list.add(stack.pop()); } for(int i=0;i<list.size();i++){ result.add(list.get(i).val); if(direction){ if(list.get(i).left!=null) stack.push(list.get(i).left); if(list.get(i).right!=null) stack.push(list.get(i).right); } else{ if(list.get(i).right!=null) stack.push(list.get(i).right); if(list.get(i).left!=null) stack.push(list.get(i).left); } } if(direction) direction = false; else direction = true; arr.add(result); } return arr; }
9.倒序層次遍歷
//倒序層次遍歷 public ArrayList<ArrayList<Integer>> levelOrderBottom(TreeNode root) { // write your code here ArrayList<ArrayList<Integer>> arr = new ArrayList<ArrayList<Integer>>(); Queue<TreeNode> q = new LinkedList<TreeNode>(); if(root!=null) q.offer(root); while(!q.isEmpty()){ ArrayList<TreeNode> list = new ArrayList<TreeNode>(); ArrayList<Integer> result = new ArrayList<Integer>(); while(!q.isEmpty()){ list.add(q.poll()); } for(int i=0;i<list.size();i++){ result.add(list.get(i).val); if(list.get(i).left!=null){ q.offer(list.get(i).left); } if(list.get(i).right!=null){ q.offer(list.get(i).right); } } arr.add(0,result); } return arr; }
10.二叉樹深度
//二叉樹深度 public int depth(TreeNode root) //樹的深度 { if(root == null) return 0; int d1,d2; d1=depth(root.left); d2=depth(root.right); return (d1>d2?d1:d2)+1; }
11.二叉樹節點數
public int CountNode(TreeNode root) { if(root == null) return 0; return 1+CountNode(root.left)+CountNode(root.right); }