
二叉树遍历算法
发布日期:2021-05-08 11:29:56
浏览次数:26
分类:精选文章
本文共 10610 字,大约阅读时间需要 35 分钟。
文章目录
1 原理
2 实现
定义二叉树节点:
/** * 二叉树节点 * * @author wgm * @since 2021/4/18 */public class BinaryTreeNode { private Integer data; private BinaryTreeNode leftChild; private BinaryTreeNode rightChild; public BinaryTreeNode(Integer data) { this.data = data; } public BinaryTreeNode setLeftChild(int data) { BinaryTreeNode node = new BinaryTreeNode(data); this.setLeftChild(node); return node; } public BinaryTreeNode setRightChild(int data) { BinaryTreeNode node = new BinaryTreeNode(data); this.setRightChild(node); return node; } @Override public String toString() { return data.toString(); } public Integer getData() { return data; } public void setData(Integer data) { this.data = data; } public BinaryTreeNode getLeftChild() { return leftChild; } public void setLeftChild(BinaryTreeNode leftChild) { this.leftChild = leftChild; } public BinaryTreeNode getRightChild() { return rightChild; } public void setRightChild(BinaryTreeNode rightChild) { this.rightChild = rightChild; }}
定义二叉树:
import java.util.LinkedList;import java.util.Stack;/** * 二叉树 * 二叉树的遍历,无论使用栈还是堆,都有绝对一致的遍历逻辑,区别仅仅在于元素打印语句的位置不一样。 * * @author wgm * @since 2021/4/18 */public class BinaryTree { private BinaryTreeNode root; public BinaryTree(BinaryTreeNode root) { this.root = root; } public static BinaryTree getInit() { BinaryTreeNode node0 = new BinaryTreeNode(0); BinaryTreeNode node1 = node0.setLeftChild(1); BinaryTreeNode node2 = node0.setRightChild(2); BinaryTreeNode node3 = node1.setLeftChild(3); BinaryTreeNode node4 = node1.setRightChild(4); BinaryTreeNode node5 = node2.setLeftChild(5); BinaryTreeNode node6 = node2.setRightChild(6); BinaryTreeNode node7 = node4.setLeftChild(7); BinaryTreeNode node8 = node4.setRightChild(8); BinaryTreeNode node9 = node6.setLeftChild(9); BinaryTreeNode node10 = node8.setRightChild(10); return new BinaryTree(node0); } /** * 前序遍历(递归/栈) * * @param recursion 是否使用递归 */ public void dlr(boolean recursion) { if (recursion) { dlr(this.root); } else { dlr(this); } System.out.println(); } private void dlr(BinaryTreeNode parent) { if (parent == null) { return; } System.out.print(parent + " "); dlr(parent.getLeftChild()); dlr(parent.getRightChild()); } private void dlr(BinaryTree tree) { if (tree == null || tree.root == null) { return; } BinaryTreeNode preVisit = null; BinaryTreeNode visit = tree.root; Stackstack = new Stack<>(); while (!stack.empty() || visit != null) { // 处理左分支 while (visit != null) { System.out.print(visit + " "); // 前序遍历,第一次访问时打印 stack.push(visit); visit = visit.getLeftChild(); } // 处理右分支 visit = stack.peek(); BinaryTreeNode rightChild = visit.getRightChild(); if (rightChild == null) { // 没有右节点 stack.pop(); preVisit = visit; visit = null; // 若令visit = stack.peek(),则会陷入访问左分支的死循环。 } else if (preVisit != rightChild) { // 没有访问过右节点 visit = rightChild; } else { // 已经访问过右节点 stack.pop(); preVisit = visit; visit = null; } } } /** * 中序遍历(递归/栈) * * @param recursion 是否使用递归 */ public void ldr(boolean recursion) { if (recursion) { ldr(this.root); } else { ldr(this); } System.out.println(); } private void ldr(BinaryTreeNode parent) { if (parent == null) { return; } ldr(parent.getLeftChild()); System.out.print(parent + " "); ldr(parent.getRightChild()); } private void ldr(BinaryTree tree) { if (tree == null || tree.root == null) { return; } BinaryTreeNode preVisit = null; BinaryTreeNode visit = tree.root; Stack stack = new Stack<>(); while (!stack.empty() || visit != null) { // 处理左分支 while (visit != null) { stack.push(visit); visit = visit.getLeftChild(); } // 处理右分支 visit = stack.peek(); BinaryTreeNode rightChild = visit.getRightChild(); if (rightChild == null) { // 没有右节点 System.out.print(visit + " "); // 中序遍历,第二次访问时打印 stack.pop(); preVisit = visit; visit = null; // 若令visit = stack.peek(),则会陷入访问左分支的死循环。 } else if (preVisit != rightChild) { // 没有访问过右节点 System.out.print(visit + " "); // 中序遍历,第二次访问时打印 visit = rightChild; } else { // 已经访问过右节点 stack.pop(); preVisit = visit; visit = null; } } } /** * 后序遍历(递归/栈) * * @param recursion 是否使用递归 */ public void lrd(boolean recursion) { if (recursion) { lrd(this.root); } else { lrd(this); } System.out.println(); } private void lrd(BinaryTreeNode parent) { if (parent == null) { return; } lrd(parent.getLeftChild()); lrd(parent.getRightChild()); System.out.print(parent + " "); } private void lrd(BinaryTree tree) { if (tree == null || tree.root == null) { return; } BinaryTreeNode preVisit = null; BinaryTreeNode visit = tree.root; Stack stack = new Stack<>(); while (!stack.empty() || visit != null) { // 处理左分支 while (visit != null) { stack.push(visit); visit = visit.getLeftChild(); } // 处理右分支 visit = stack.peek(); BinaryTreeNode rightChild = visit.getRightChild(); if (rightChild == null) { // 没有右节点 System.out.print(visit + " "); // 后序遍历,第三次访问时打印 stack.pop(); preVisit = visit; visit = null; // 若令visit = stack.peek(),则会陷入访问左分支的死循环。 } else if (preVisit != rightChild) { // 没有访问过右节点 visit = rightChild; } else { // 已经访问过右节点 System.out.print(visit + " "); // 后序遍历,第三次访问时打印 stack.pop(); preVisit = visit; visit = null; } } } /** * 层序遍历(队列) */ public void level() { if (this.root == null) { return; } BinaryTreeNode visit = this.root; LinkedList queue = new LinkedList<>(); queue.offer(visit); while (!queue.isEmpty()) { visit = queue.poll(); System.out.print(visit + " "); BinaryTreeNode leftChild = visit.getLeftChild(); if (leftChild != null) { queue.offer(leftChild); } BinaryTreeNode rightChild = visit.getRightChild(); if (rightChild != null) { queue.offer(rightChild); } } System.out.println("\r\n"); } @Override public String toString() { return "BinaryTree{" + "root=" + root + '}'; } public BinaryTreeNode getRoot() { return root; } public void setRoot(BinaryTreeNode root) { this.root = root; }}
编写测试类:
/** * 测试 * * @author wgm * @since 2021/4/18 */public class BinaryTreeTest { public static void main(String[] args) { BinaryTree tree = BinaryTree.getInit(); System.out.print("\r\n前序遍历(递归):\t"); tree.dlr(true); System.out.print("前序遍历(栈):\t"); tree.dlr(false); System.out.print("\r\n中序遍历(递归):\t"); tree.ldr(true); System.out.print("中序遍历(栈):\t"); tree.ldr(false); System.out.print("\r\n后序遍历(递归):\t"); tree.lrd(true); System.out.print("后序遍历(栈):\t"); tree.lrd(false); System.out.print("\r\n层序遍历(队列):\t"); tree.level(); }}
3 测试
D:\program\Java\jdk1.8.0_241\bin\java.exe -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:55438,suspend=y,server=n "-javaagent:C:\Users\GMWANG~1\AppData\Local\Temp\captureAgent2401jars\debugger-agent.jar" -Dfile.encoding=UTF-8 -classpath "D:\program\Java\jdk1.8.0_241\jre\lib\charsets.jar;D:\program\Java\jdk1.8.0_241\jre\lib\deploy.jar;D:\program\Java\jdk1.8.0_241\jre\lib\ext\access-bridge-64.jar;D:\program\Java\jdk1.8.0_241\jre\lib\ext\cldrdata.jar;D:\program\Java\jdk1.8.0_241\jre\lib\ext\dnsns.jar;D:\program\Java\jdk1.8.0_241\jre\lib\ext\jaccess.jar;D:\program\Java\jdk1.8.0_241\jre\lib\ext\jfxrt.jar;D:\program\Java\jdk1.8.0_241\jre\lib\ext\localedata.jar;D:\program\Java\jdk1.8.0_241\jre\lib\ext\nashorn.jar;D:\program\Java\jdk1.8.0_241\jre\lib\ext\sunec.jar;D:\program\Java\jdk1.8.0_241\jre\lib\ext\sunjce_provider.jar;D:\program\Java\jdk1.8.0_241\jre\lib\ext\sunmscapi.jar;D:\program\Java\jdk1.8.0_241\jre\lib\ext\sunpkcs11.jar;D:\program\Java\jdk1.8.0_241\jre\lib\ext\zipfs.jar;D:\program\Java\jdk1.8.0_241\jre\lib\javaws.jar;D:\program\Java\jdk1.8.0_241\jre\lib\jce.jar;D:\program\Java\jdk1.8.0_241\jre\lib\jfr.jar;D:\program\Java\jdk1.8.0_241\jre\lib\jfxswt.jar;D:\program\Java\jdk1.8.0_241\jre\lib\jsse.jar;D:\program\Java\jdk1.8.0_241\jre\lib\management-agent.jar;D:\program\Java\jdk1.8.0_241\jre\lib\plugin.jar;D:\program\Java\jdk1.8.0_241\jre\lib\resources.jar;D:\program\Java\jdk1.8.0_241\jre\lib\rt.jar;D:\project\untitled\out\production\untitled;D:\program\JetBrains\IntelliJ IDEA 2020.1\lib\idea_rt.jar" BinaryTreeTestConnected to the target VM, address: '127.0.0.1:55438', transport: 'socket'前序遍历(递归): 0 1 3 4 7 8 10 2 5 6 9 前序遍历(栈): 0 1 3 4 7 8 10 2 5 6 9 中序遍历(递归): 3 1 7 4 8 10 0 5 2 9 6 中序遍历(栈): 3 1 7 4 8 10 0 5 2 9 6 后序遍历(递归): 3 7 10 8 4 1 5 9 6 2 0 后序遍历(栈): 3 7 10 8 4 1 5 9 6 2 0 层序遍历(队列): 0 1 2 3 4 5 6 7 8 9 10 Disconnected from the target VM, address: '127.0.0.1:55438', transport: 'socket'Process finished with exit code 0
发表评论
最新留言
感谢大佬
[***.8.128.20]2025年04月14日 04时18分55秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
ReactJs入门教程-精华版
2021-05-09
乐观锁悲观锁应用
2021-05-09
简单说说TCP三次握手、四次挥手机制
2021-05-09
.net Core 使用IHttpClientFactory请求
2021-05-09
多线程之旅(准备阶段)
2021-05-09
Python 之网络式编程
2021-05-09
MySql5.5安装步骤及MySql_Front视图配置
2021-05-09
springmvc Controller详解
2021-05-09
mybatis #{}和${}区别
2021-05-09
Java Objects工具类重点方法使用
2021-05-09
Java内存模型(JMM)
2021-05-09
AQS相关
2021-05-09
abp(net core)+easyui+efcore实现仓储管理系统——多语言(十)
2021-05-09
WCF学习之旅—第三个示例之一(二十七)
2021-05-09
java ThreadPoolExecutor初探
2021-05-09