二叉树--遍历
2016-05-23 19:52
288 查看
三种遍历方式 |
static void visit(TreeNode root) { System.out.println(root.key + "----------->" + root.value); } //先序遍历 static void preOrder(TreeNode root) { if (root != null) { visit(root); preOrder(root.left); preOrder(root.right); } } public static void preOrderImpl01(TreeNode node) { if (node == null) return; LinkedList<TreeNode> stack = new LinkedList<TreeNode>(); stack.push(node); while (!stack.isEmpty()) { TreeNode temp = stack.pop(); visit(temp); if (temp.right != null) stack.push(temp.right); if (temp.left != null) stack.push(temp.left); } }
非递归解释:采用栈,先压入根节点,接着出栈,压入右节点,左节点,下一次左节点出栈,压入左节点的左右节点,西安便利左子树,再遍历右子树,输出的顺序为先序遍历中–>左–>右
//中序遍历 static void inOrder(TreeNode root) { if (root != null) { midOrder(root.left); visit(root); midOrder(root.right); } } static void inOrder(TreeNode root) { LinkedList<TreeNode> stack = new LinkedList<BinaryTree.TreeNode>(); TreeNode node = root; while (node != null || !stack.isEmpty()) { while (node != null) { stack.push(node); node = node.left; } node = stack.pop(); visit(node); node = node.right; if (node != null) { stack.push(node); node = node.left; } } }
非递归解释:采用栈,先压入根节点,接着依次压入左节点,下一次左节点出栈,如果该点有右子树,则右节点进栈,节点右节点的左节点,这样进行下一次循环时,就可以进行while的左子树压栈,保证左子树有限进栈;如果该点无右子树,则node赋值为空,可以保证不进入上面while的循环。先便利左子树,再遍历右子树,输出的顺序为先序遍历左–>中–>右
//后序遍历 static void postOrder(TreeNode root) { if (root != null) { postOrder(root.left); postOrder(root.right); visit(root); } } public static void postOrder(TreeNode node) { if (node == null) return; LinkedList<TreeNode> stack = new LinkedList<TreeNode>(); stack.push(node); while (!stack.isEmpty()) { TreeNode curr = stack.peek(); if (!curr.flag) { if (curr.right != null) { stack.push(curr.right); } if (curr.left != null) { System.out.println(curr.left.value); stack.push(curr.left); } curr.flag = true; } TreeNode temp = stack.peek(); if (temp.flag == true) { visit(stack.pop()); } } } //不使用标记flag的方法 public List<Integer> postorderTraversal(TreeNode root) { Deque<TreeNode> stack = new LinkedList<>(); stack.push(root); List<Integer> ret = new ArrayList<>(); while (!stack.isEmpty()) { TreeNode node = stack.pop(); if (node != null) { ret.add(node.val); stack.push(node.left); stack.push(node.right); } } Collections.reverse(ret); return ret; }
非递归解释:这个里边增加了节点访问标记,采用栈,先压入根节点,接着压入右节点,左节点,然后取栈顶元素,看是否符合输出条件(不到左子树的最作边节点,就不符合输出条件),直到最左边的一个中–>右–>左结构压栈,下一次进行出栈,则是左,右,中,如果右节点上还有子树,进入上面的if,再进行先前的操作,这样左子树就遍历完成,接着会遍历右子树,最后返回根节点,输出的顺序为先序遍历左–>右–>中
树的结构如下:
public static class TreeNode { int key; Object value; boolean flag; TreeNode left; TreeNode right; TreeNode(int key, Object value) { this.value = value; this.key = key; } }
层次遍历 |
public List<List<Integer>> levelOrder(TreeNode root) { List<List<Integer>> list = new LinkedList<>(); if (root == null) return list; List<TreeNode> nodeList = new ArrayList<>(); TreeNode node = root; nodeList.add(node); int len = 1; int count = 0; while (count < len) { List<Integer> valueList = new LinkedList<>(); while (count < len) { TreeNode nodeTemp = nodeList.get(count); valueList.add(nodeTemp.val); if (nodeTemp.left != null) { nodeList.add(nodeTemp.left); } if (nodeTemp.right != null) { nodeList.add(nodeTemp.right); } count++; } len = nodeList.size(); list.add(valueList); } return list; }
这个代码比较简单,博主自己实现的,所以代码看着比较乱一点,同时也可以采用队列的结构,来实现层次遍历。
相关文章推荐
- iOS更改tabbar图片渲染 —不让tabbat有蓝色的渲染 并修改文字
- sh_脚本语法
- Unity3d Hierarchy 中 拷贝选中Node 的层级路径
- 第12周阅读程序(2)
- MFC嵌入浏览器框架CEF
- Ubuntu配置LAMP+MediaWiki及常见问题
- 沼泽鳄鱼 矩阵乘法
- Node.js简介
- Date picker 控件简介
- JUnit单元测试--JUnit简介
- csu 1329 一行盒子
- 10267 - Graphical Editor
- 奶牛接力 矩阵乘法
- POJ 3237 Tree (树链剖分 路径剖分 线段树的lazy标记)
- poj2352题解
- 家谱 并差集
- Recycleview 使用中的问题
- 《学习笔记》之JAVA设计模式--原型模式
- 成为程序员的一些基本"法则"
- 百度地图--定位