//前序遍历 /** * 根-左-右,所以入栈的时候要相反,有右节点则加入右节点,有左节点则加入左节点,每车循环的时候,弹一个 */ public ArrayList<Integer> preorderTraversal(TreeNode root) { ArrayList<Integer> list = new ArrayList(); Stack<TreeNode> stack = new Stack(); if (root == null){ return list; } stack.push(root); while (!stack.isEmpty()){ TreeNode temp = stack.pop(); list.add(temp.val); if (temp.right!=null){ stack.push(temp.right); } if (temp.left!=null){ stack.push(temp.left); } } return list; }
// 中序遍历 非递归算法 public static void InOrder2(TreeNode root) { if(root==null)return; Stack<TreeNode> stk = new Stack<TreeNode>(); TreeNode p = root;//辅助节点 stk.add(p); while(stk.isEmpty() == false) { //只要你有左孩子,就将左孩子压入栈中 if(p!=null && p.left!=null) { stk.add(p.left); p = p.left; }else { p = stk.pop();//弹出栈顶节点 左孩子--->根节点 System.out.print(p.val+" ");//访问 if(p!=null && p.right!=null) {//如果栈点元素有右孩子的话,将有节点压入栈中 stk.add(p.right); p = p.right; }else p = null;//p=stk.pop;已经访问过p了,p设置为null } } }
/** * 后序遍历 */ public static void postOrderFast(TreeNode root) { if (root == null) { return; } Stack<TreeNode> s1 = new Stack<>(); Stack<TreeNode> s2 = new Stack<>(); s1.push(root); TreeNode curNode; while(!s1.isEmpty()) { curNode = s1.pop(); // 中、右、左顺序压入栈中 s2.push(curNode); // 压入s1为先左后右,保证中、右、左顺序压入s2中 if (curNode.left != null) { s1.push(curNode.left); } if (curNode.right != null) { s1.push(curNode.right); } } while (!s2.isEmpty()) { System.out.print(s2.pop().val + " "); } }
个人书写(和上发写法思想一致):
使用:
public static void main(String[] args) { WriteMethod clazz=new WriteMethod(); TreeNode treeNode = clazz.initTreeNode(new int[]{1, 2, 3, 4, 5, 6, 7}); clazz.preOrderBinaryTree(treeNode); clazz.inOrderBinaryTree(treeNode); clazz.postOrderBinaryTree(treeNode); }
TreeNode initTreeNode(int[] arr){ if(arr==null||arr.length==0)return null; List<TreeNode> list=new ArrayList<>(); int len=arr.length; for (int i = 0; i < len; i++) { list.add(new TreeNode(arr[i])); } for (int i = 0; i < len; i++) { if(2*i+1<len){ list.get(i).left=list.get(2*i+1); } else { list.get(i).left=null; } if(2*i+2<len){ list.get(i).right=list.get(2*i+2); } else { list.get(i).right=null; } } return list.get(0); }
void preOrderBinaryTree(TreeNode treeNode){ Stack<TreeNode> stack=new Stack<>(); stack.push(treeNode); TreeNode curNode; System.out.print("前序遍历:"); while (!stack.isEmpty()){ curNode=stack.pop(); System.out.print(curNode.val+" "); if(curNode.right!=null){ stack.push(curNode.right); } if(curNode.left!=null){ stack.push(curNode.left); } } System.out.println(); }
void inOrderBinaryTree(TreeNode treeNode){ Stack<TreeNode> stack=new Stack<>(); stack.push(treeNode); TreeNode p=treeNode; System.out.print("中序遍历:"); while (!stack.isEmpty()){ if(p!=null&&p.left!=null){ p=p.left; stack.push(p); } else { p=stack.pop(); System.out.print(p.val+" "); if(p!=null&&p.right!=null){ p=p.right; stack.push(p); } else { p=null; } } } System.out.println(); }
void postOrderBinaryTree(TreeNode treeNode){ Stack<Integer> resStack=new Stack<>();//顺序是上,右,左 Stack<TreeNode> stack=new Stack<>();//需要给resStack的顺序也就是上方他需要的顺序,他要右然后左,因此右在我的上面,左在下面,因此压入的顺序就是先压左,再压右 stack.push(treeNode); TreeNode curNode; while (!stack.isEmpty()){ curNode=stack.pop(); resStack.push(curNode.val); if(curNode.left!=null){ stack.push(curNode.left); } if(curNode.right!=null){ stack.push(curNode.right); } } System.out.print("后序遍历:"); while (!resStack.isEmpty()){ System.out.print(resStack.pop()+" "); } }
public List<Integer> postorderTraversal(TreeNode root) { LinkedList<Integer> list = new LinkedList<>(); Stack<TreeNode> stack = new Stack<>(); if(root != null) stack.push(root); while(!stack.isEmpty()) { TreeNode p = stack.pop(); list.addFirst(p.val); if(p.left != null) stack.add(p.left); if(p.right != null) stack.add(p.right); } return list; }
实例结果:
前序遍历:1 2 4 5 3 6 7 中序遍历:4 2 5 1 6 3 7 后序遍历:4 5 2 6 7 3 1