二叉树遍历(前序遍历,中序遍历,后序遍历)
来源:互联网 发布:ubuntu极点五笔安装 编辑:程序博客网 时间:2024/05/16 23:41
原文链接:http://www.dubby.cn/detail.html?id=9056
定义树的节点类型(为节省篇幅省略了getter/setter):
public class TreeNode<T> { private T value; private TreeNode<T> left; private TreeNode<T> right;}
前序遍历
前序遍历Preorder Traversal (DLR),是二叉树遍历的一种,也叫做先根遍历、先序遍历、前序周游,可记做根左右。前序遍历首先访问根结点然后遍历左子树,最后遍历右子树。
前序遍历结果:ABDECF
已知后序遍历和中序遍历,就能确定前序遍历。
递归
public List<T> travelWithRecursion(TreeNode<T> tree) { List<T> result = new ArrayList<>(); doTravelRecursion(tree, result); return result;}private void doTravelRecursion(TreeNode<T> tree, List<T> result) { if (tree == null) return; result.add(tree.getValue()); if (tree.getLeft() != null) doTravelRecursion(tree.getLeft(), result); if (tree.getRight() != null) doTravelRecursion(tree.getRight(), result);}
非递归
public List<T> travelWithoutRecursion(TreeNode<T> tree) { List<T> result = new ArrayList<>(); Stack<TreeNode<T>> stack = new Stack<>(); stack.push(tree); while (!stack.empty()) { TreeNode<T> node = stack.pop(); result.add(node.getValue()); if (node.getRight() != null) { stack.push(node.getRight()); } if (node.getLeft() != null) { stack.push(node.getLeft()); } } return result;}
中序遍历
中序遍历Inorder Traversal (LDR)是二叉树遍历的一种,也叫做中根遍历、中序周游。在二叉树中,先左后根再右。巧记:左根右。
中序遍历结果:DBEAFC
递归
public List<T> travelWithRecursion(TreeNode<T> tree) { List<T> result = new ArrayList<>(); doTravelRecursion(tree, result); return result;}private void doTravelRecursion(TreeNode<T> tree, List<T> result) { if (tree == null) return; if (tree.getLeft() != null) doTravelRecursion(tree.getLeft(), result); result.add(tree.getValue()); if (tree.getRight() != null) doTravelRecursion(tree.getRight(), result);}
非递归
public List<T> travelWithoutRecursion(TreeNode<T> tree) { List<T> result = new ArrayList<>(); Stack<TreeNode<T>> stack = new Stack<>(); TreeNode<T> node = tree; while (!stack.empty() || node != null) { while (node != null) { stack.push(node); node = node.getLeft(); } if (!stack.empty()) { node = stack.pop(); result.add(node.getValue()); node = node.getRight(); } } return result;}
后序遍历
后序遍历Postorder Traversal (LRD)是二叉树遍历的一种,也叫做后根遍历、后序周游,可记做左右根。后序遍历有递归算法和非递归算法两种。在二叉树中,先左后右再根。巧记:左右根。
后序遍历结果:DEBFCA
已知前序遍历和中序遍历,就能确定后序遍历。
递归
public List<T> travelWithRecursion(TreeNode<T> tree) { List<T> result = new ArrayList<>(); doTravelRecursion(tree, result); return result;}private void doTravelRecursion(TreeNode<T> tree, List<T> result) { if (tree == null) return; if (tree.getLeft() != null) doTravelRecursion(tree.getLeft(), result); if (tree.getRight() != null) doTravelRecursion(tree.getRight(), result); result.add(tree.getValue());}
非递归
public List<T> travelWithoutRecursion(TreeNode<T> tree) { List<T> result = new ArrayList<>(); Stack<TreeNode<T>> stack = new Stack<>(); TreeNode<T> currentNode = tree; TreeNode<T> lastNode = null; while (currentNode != null) { stack.push(currentNode); currentNode = currentNode.getLeft(); } while (!stack.empty()) { currentNode = stack.pop(); //只有“当前节点”没有右孩子或者右孩子已经被访问过了,才可以访问“当前节点” if (currentNode.getRight() == null || currentNode.getRight() == lastNode) { result.add(currentNode.getValue()); lastNode = currentNode; } else { stack.push(currentNode); currentNode = currentNode.getRight(); while (currentNode != null) { stack.push(currentNode); currentNode = currentNode.getLeft(); } } } return result;}
测试
public class Test { public static void main(String[] args) { TreeNode<String> root = prepareData(); PreOrder<String> preOrder = new PreOrder<>(); InOrder<String> inOrder = new InOrder<>(); PostOrder<String> postOrder = new PostOrder<>(); System.out.println("先序遍历\t\t" + String.join(", ", preOrder.travelWithoutRecursion(root))); System.out.println("先序遍历\t\t" + String.join(", ", preOrder.travelWithRecursion(root))); System.out.println(); System.out.println("中序遍历\t\t" + String.join(", ", inOrder.travelWithoutRecursion(root))); System.out.println("中序遍历\t\t" + String.join(", ", inOrder.travelWithRecursion(root))); System.out.println(); System.out.println("后序遍历\t\t" + String.join(", ", postOrder.travelWithoutRecursion(root))); System.out.println("后序遍历\t\t" + String.join(", ", postOrder.travelWithRecursion(root))); System.out.println(); } /** * 1 * 2 3 * 4 5 6 7 */ private static TreeNode<String> prepareData() { TreeNode<String> root = new TreeNode<>(); root.setValue("1"); TreeNode<String> node1 = new TreeNode<>(); node1.setValue("2"); root.setLeft(node1); TreeNode<String> node1_1 = new TreeNode<>(); node1_1.setValue("4"); node1.setLeft(node1_1); TreeNode<String> node1_2 = new TreeNode<>(); node1_2.setValue("5"); node1.setRight(node1_2); TreeNode<String> node2 = new TreeNode<>(); node2.setValue("3"); root.setRight(node2); TreeNode<String> node2_1 = new TreeNode<>(); node2_1.setValue("6"); node2.setLeft(node2_1); TreeNode<String> node2_2 = new TreeNode<>(); node2_2.setValue("7"); node2.setRight(node2_2); return root; }}
结果:
先序遍历 1, 2, 4, 5, 3, 6, 7先序遍历 1, 2, 4, 5, 3, 6, 7中序遍历 4, 2, 5, 1, 6, 3, 7中序遍历 4, 2, 5, 1, 6, 3, 7后序遍历 4, 5, 2, 6, 7, 3, 1后序遍历 4, 5, 2, 6, 7, 3, 1
源代码地址:https://github.com/dubby1994/tree-traversal
参考文章
- 二叉树前序、中序、后序遍历非递归写法的透彻解析
阅读全文
0 0
- 二叉树遍历(Java)---前序遍历,中序遍历,后序遍历
- 二叉树的遍历(前序遍历、中序遍历、后序遍历)
- 二叉树遍历(前序遍历,中序遍历,后序遍历)
- 二叉树--前序遍历、中序遍历、后序遍历、层次遍历
- 二叉树的遍历 前序遍历 中序遍历 后序遍历
- 二叉树的遍历:前序遍历、中序遍历和后序遍历
- java实现根据前序遍历构建二叉树(前序遍历、中序遍历、后序遍历)
- 二叉树的遍历,二叉树的创建、前序遍历、中序遍历、后序遍历 (转)
- 二叉树的前序遍历,中序遍历和后序遍历(c#)
- 二叉树---(3)前序遍历,中序遍历,后序遍历
- C++实现二叉树 前序遍历, 后序遍历, 中序遍历, 层序遍历(不用递归)
- 【原创】二叉树的建立与遍历(前序遍历、中序遍历、后序遍历)
- 树 前序遍历,中序遍历,后序遍历
- 树的前序遍历,中序遍历,后序遍历,层次(广度)遍历
- 二叉树的创建、前序遍历、中序遍历、后序遍历
- 二叉树的创建、前序遍历、中序遍历、后序遍历
- 二叉树的创建、前序遍历、中序遍历、后序遍历
- 二叉树的创建、前序遍历、中序遍历、后序遍历
- java 自定义类如何实现foreach循环
- 数据分析技术:结构方程模型;想要“追求”,了解是第一步
- Eclipse重置
- wifi密码锁-ESP8266简单应用
- 如何理解JavaScript闭包问题
- 二叉树遍历(前序遍历,中序遍历,后序遍历)
- 分页查询产品信息,第五步:完成产品的分页显示
- 如何在csdn.net中转载文章(修改版,大神吴鹏)
- Linux(Ubuntu 16.04)的远程登录
- Subband AF 和Block transforms AF的比较
- 解决方法 一.高度塌陷和 二.垂直外边距重叠的问题
- 分页查询产品信息,第六步;封装结果
- qml学习笔记(一):界面元素初探
- 高级软件工程课程总结