标签:循环 post 包括 一个 层序遍历 变量 非递归 empty else
先序遍历:根-->左-->右的形式
public static void preOrderTraveralWithStsck(Node node){ Stack<Node> stack = new Stack(); //当节点的左右孩子全为空并且,栈空表示遍历完毕 while (node != null || !stack.isEmpty()) { //访问左孩子并且入栈 while (node != null) { System.out.print(node.date + " "); stack.push(node); node = node.left; } // 左孩子遍历完毕,遍历右孩子(栈不为空说明还么有遍历完毕) if (!stack.isEmpty()) { node = stack.pop(); node = node.right; } } }
中序遍历:左-->根-->右的形式,与先序遍历很相似,只是打印的位置不同。(相对来说是最简单的)
public static void inOrderTraveralWithStack(Node node){ Stack<Node> stack = new Stack<>(); while (node != null || !stack.isEmpty()){ while (node != null){ stack.push(node); node = node.left; } if(!stack.isEmpty()){ node = stack.pop(); System.out.print(node.date+" "); node = node.right; } } }
后序遍历:左-->右-->根,相比前两种遍历,其应该是最难得,从上面两种遍历可以看出,都是先从根结点出发,依次的找出相对的所有左孩子,然后会出栈到它相对的根结点,再次判断,因此在后序遍历中,访问完左孩子,接下来应该是访问右孩子,所以就应该引入一个变量来记录根结点其右孩子的情况(包括不存在和已经访问过得情况)。
public static void postOrderTraverTraveralWithStack(Node node){ Stack<Node> stack = new Stack<>(); Node pre = null; //上次访问的节点 while (node != null || !stack.isEmpty()){ //将根结点以及所有左孩子入栈 while (node != null){ stack.push(node); node = node.left; } //走到这说明该节点的左孩子为空了,接下来只需要判断右孩子 if(!stack.isEmpty()){ //获取栈顶元素 Node top = stack.peek(); //如果栈顶元素的右孩子不存在或者已经被访问了,则输出栈顶元素 if(top.right == null || top.right == pre){ node = stack.pop(); System.out.print(node.date+" "); //为本次访问的节点赋值 pre = node; //更新node,很重要否则会进入死循环,(为了访问该节点的根结点) node = null; }//找到栈顶元素的右孩子,并且会将右孩子压入栈(while中),继续迭代 else { node = top.right; } } } }
层序遍历:按层次关系,横向遍历
// 层序遍历 public static void levelOrderTraver(Node node){ Queue<Node> queue = new LinkedList<>(); // 插入根结点 queue.offer(node); while (!queue.isEmpty()){ Node pop = queue.poll(); System.out.print(pop.date+" "); if(pop.left != null){ queue.offer(pop.left); } if(pop.right != null){ queue.offer(pop.right); } } }
二叉树的三种遍历非递归实现(栈) 以及层序遍历(队列)(java)
标签:循环 post 包括 一个 层序遍历 变量 非递归 empty else
原文地址:https://www.cnblogs.com/128-cdy/p/13382943.html