java实现二叉树的创建及5种遍历方法(总结)

发布时间 - 2026-01-11 00:34:57    点击率:

用java实现的数组创建二叉树以及递归先序遍历,递归中序遍历,递归后序遍历,非递归前序遍历,非递归中序遍历,非递归后序遍历,深度优先遍历,广度优先遍历8种遍历方式:

package myTest;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;

public class myClass {
 
 public static void main(String[] args) {
 // TODO Auto-generated method stub
 myClass tree = new myClass();
 int[] datas = new int[]{1,2,3,4,5,6,7,8,9};
 List<Node> nodelist = new LinkedList<>();
 tree.creatBinaryTree(datas, nodelist);
 Node root = nodelist.get(0);
 System.out.println("递归先序遍历:");
 tree.preOrderTraversal(root);
 System.out.println();
 System.out.println("非递归先序遍历:");
 tree.preOrderTraversalbyLoop(root);
 System.out.println();
 System.out.println("递归中序遍历:");
 tree.inOrderTraversal(root);
 System.out.println();
 System.out.println("非递归中序遍历:");
 tree.inOrderTraversalbyLoop(root);
 System.out.println();
 System.out.println("递归后序遍历:");
 tree.postOrderTraversal(root);
 System.out.println();
 System.out.println("非递归后序遍历:");
 tree.postOrderTraversalbyLoop(root);
 System.out.println();
 System.out.println("广度优先遍历:");
 tree.bfs(root);
 System.out.println();
 System.out.println("深度优先遍历:");
 List<List<Integer>> rst = new ArrayList<>();
 List<Integer> list = new ArrayList<>();
 tree.dfs(root,rst,list);
 System.out.println(rst);
 }
 /**
 * 
 * @param datas 实现二叉树各节点值的数组
 * @param nodelist 二叉树list
 */
 private void creatBinaryTree(int[] datas,List<Node> nodelist){
 //将数组变成node节点
 for(int nodeindex=0;nodeindex<datas.length;nodeindex++){
  Node node = new Node(datas[nodeindex]);
  nodelist.add(node);
 }
 //给所有父节点设定子节点
 for(int index=0;index<nodelist.size()/2-1;index++){
  //编号为n的节点他的左子节点编号为2*n 右子节点编号为2*n+1 但是因为list从0开始编号,所以还要+1
  //这里父节点有1(2,3),2(4,5),3(6,7),4(8,9) 但是最后一个父节点有可能没有右子节点 需要单独处理
  nodelist.get(index).setLeft(nodelist.get(index*2+1)); 
  nodelist.get(index).setRight(nodelist.get(index*2+2));
 }
 //单独处理最后一个父节点 因为它有可能没有右子节点
 int index = nodelist.size()/2-1;
 nodelist.get(index).setLeft(nodelist.get(index*2+1)); //先设置左子节点
 if(nodelist.size() % 2 == 1){ //如果有奇数个节点,最后一个父节点才有右子节点
  nodelist.get(index).setRight(nodelist.get(index*2+2));
 }
 }
 /**
 * 遍历当前节点的值
 * @param nodelist
 * @param node
 */
 public void checkCurrentNode(Node node){
 System.out.print(node.getVar()+" ");
 }
 /**
 * 先序遍历二叉树
 * @param root 二叉树根节点
 */
 public void preOrderTraversal(Node node){
 if (node == null) //很重要,必须加上 当遇到叶子节点用来停止向下遍历
      return; 
 checkCurrentNode(node);
 preOrderTraversal(node.getLeft());
 preOrderTraversal(node.getRight());
 }
 /**
 * 中序遍历二叉树
 * @param root 根节点
 */
 public void inOrderTraversal(Node node){
 if (node == null) //很重要,必须加上
      return; 
 inOrderTraversal(node.getLeft());
 checkCurrentNode(node);
 inOrderTraversal(node.getRight());
 }
 /**
 * 后序遍历二叉树
 * @param root 根节点
 */
 public void postOrderTraversal(Node node){
 if (node == null) //很重要,必须加上
      return; 
 postOrderTraversal(node.getLeft());
 postOrderTraversal(node.getRight());
 checkCurrentNode(node);
 }
 
 /**
 * 非递归前序遍历
 * @param node
 */
 public void preOrderTraversalbyLoop(Node node){
 Stack<Node> stack = new Stack();
 Node p = node;
 while(p!=null || !stack.isEmpty()){
  while(p!=null){ //当p不为空时,就读取p的值,并不断更新p为其左子节点,即不断读取左子节点
  checkCurrentNode(p);
  stack.push(p); //将p入栈
  p = p.getLeft();
  }
  if(!stack.isEmpty()){
  p = stack.pop();
  p = p.getRight();
  }
 }
 }
 /**
 * 非递归中序遍历
 * @param node
 */
 public void inOrderTraversalbyLoop(Node node){
 Stack<Node> stack = new Stack();
 Node p = node;
 while(p!=null || !stack.isEmpty()){
  while(p!=null){
  stack.push(p);
  p = p.getLeft();
  }
  if(!stack.isEmpty()){ 
  p = stack.pop();
  checkCurrentNode(p);
  p = p.getRight();
  }
 }
 }
 /**
 * 非递归后序遍历
 * @param node
 */
 public void postOrderTraversalbyLoop(Node node){
 Stack<Node> stack = new Stack<>();
 Node p = node,prev = node;
 while(p!=null || !stack.isEmpty()){
  while(p!=null){
  stack.push(p);
  p = p.getLeft();
  }
  if(!stack.isEmpty()){
  Node temp = stack.peek().getRight();
  if(temp == null||temp == prev){
   p = stack.pop();
   checkCurrentNode(p);
   prev = p;
   p = null;
  }else{
   p = temp;
  } 
  }
 }
 }
 
 /**
 * 广度优先遍历(从上到下遍历二叉树)
 * @param root
 */
 public void bfs(Node root){
  if(root == null) return;
  LinkedList<Node> queue = new LinkedList<Node>();
  queue.offer(root); //首先将根节点存入队列
  //当队列里有值时,每次取出队首的node打印,打印之后判断node是否有子节点,若有,则将子节点加入队列
  while(queue.size() > 0){ 
  Node node = queue.peek();
   queue.poll(); //取出队首元素并打印
   System.out.print(node.var+" ");
   if(node.left != null){ //如果有左子节点,则将其存入队列
    queue.offer(node.left);
   }
   if(node.right != null){ //如果有右子节点,则将其存入队列
    queue.offer(node.right);
   }
  }
 }
 /**
 * 深度优先遍历
 * @param node
 * @param rst
 * @param list
 */
 public void dfs(Node node,List<List<Integer>> rst,List<Integer> list){
 if(node == null) return;
 if(node.left == null && node.right == null){
  list.add(node.var);
  /* 这里将list存入rst中时,不能直接将list存入,而是通过新建一个list来实现,
  * 因为如果直接用list的话,后面remove的时候也会将其最后一个存的节点删掉*/
  rst.add(new ArrayList<>(list));
  list.remove(list.size()-1);
 }
 list.add(node.var);
 dfs(node.left,rst,list);
 dfs(node.right,rst,list);
 list.remove(list.size()-1);
 }
 /**
 * 节点类
 * var 节点值
 * left 节点左子节点
 * right 右子节点
 */ 
 class Node{
 int var;
 Node left;
 Node right;
 public Node(int var){
  this.var = var;
  this.left = null;
  this.right = null;
 }
 public void setLeft(Node left) {
  this.left = left;
 }
 public void setRight(Node right) {
  this.right = right;
 }
 public int getVar() {
  return var;
 }
 public void setVar(int var) {
  this.var = var;
 }
 public Node getLeft() {
  return left;
 }
 public Node getRight() {
  return right;
 }
 
 }

}

运行结果:

递归先序遍历:
1 2 4 8 9 5 3 6 7

非递归先序遍历:
1 2 4 8 9 5 3 6 7

递归中序遍历:
8 4 9 2 5 1 6 3 7

非递归中序遍历:
8 4 9 2 5 1 6 3 7

递归后序遍历:
8 9 4 5 2 6 7 3 1

非递归后序遍历:
8 9 4 5 2 6 7 3 1

广度优先遍历:
1 2 3 4 5 6 7 8 9

深度优先遍历:
[[1, 2, 4, 8], [1, 2, 4, 9], [1, 2, 5], [1, 3, 6], [1, 3, 7]]

以上这篇java实现二叉树的创建及5种遍历方法(总结)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。


# 二叉树的创建和遍历  # Java递归遍历树形结构的实现代码  # Java遍历输出指定目录、树形结构所有文件包括子目录下的文件  # 图解二叉树的三种遍历方式及java实现代码  # 图解红黑树及Java进行红黑二叉树遍历的方法  # Java实现二叉树的深度优先遍历和广度优先遍历算法示例  # java实现遍历树形菜单两种实现代码分享  # Java二叉树的四种遍历方式详解  # 简单谈谈Java遍历树深度优先和广度优先的操作方式  # 遍历  # 递归  # 二叉树  # 很重要  # 则将  # 有可能  # 给大家  # 也会  # 将其  # 希望能  # 才有  # 为其  # 因为它  # 若有  # 这篇  # 来实现  # 小编  # 数个  # 不断更新  # 大家多多 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Laravel怎么使用Markdown渲染文档_Laravel将Markdown内容转HTML页面展示【实战】  如何做网站制作流程,*游戏网站怎么搭建?  javascript中的数组方法有哪些_如何利用数组方法简化数据处理  如何彻底删除建站之星生成的Banner?  Laravel怎么防止CSRF攻击_Laravel CSRF保护中间件原理与实践  uc浏览器二维码扫描入口_uc浏览器扫码功能使用地址  php增删改查怎么学_零基础入门php数据库操作必知基础【教程】  WordPress 子目录安装中正确处理脚本路径的完整指南  Python企业级消息系统教程_KafkaRabbitMQ高并发应用  Laravel如何构建RESTful API_Laravel标准化API接口开发指南  Windows10如何更改计算机工作组_Win10系统属性修改Workgroup  Swift中循环语句中的转移语句 break 和 continue  mc皮肤壁纸制作器,苹果平板怎么设置自己想要的壁纸我的世界?  Laravel中间件如何使用_Laravel自定义中间件实现权限控制  免费视频制作网站,更新又快又好的免费电影网站?  猪八戒网站制作视频,开发一个猪八戒网站,大约需要多少?或者自己请程序员,需要什么程序员,多少程序员能完成?  怎么用AI帮你设计一套个性化的手机App图标?  如何在阿里云通过域名搭建网站?  HTML5打空格有哪些误区_新手常犯的空格使用错误【技巧】  Android仿QQ列表左滑删除操作  在线ppt制作网站有哪些软件,如何把网页的内容做成ppt?  Android滚轮选择时间控件使用详解  高防服务器租用指南:配置选择与快速部署攻略  Laravel Livewire是什么_使用Laravel Livewire构建动态前端界面  PythonWeb开发入门教程_Flask快速构建Web应用  高端建站如何打造兼具美学与转化的品牌官网?  悟空浏览器如何设置小说背景色_悟空浏览器背景色设置【方法】  详解Android中Activity的四大启动模式实验简述  Android中Textview和图片同行显示(文字超出用省略号,图片自动靠右边)  如何在 Python 中将列表项按字母顺序编号(a.、b.、c. …)  php结合redis实现高并发下的抢购、秒杀功能的实例  大连网站制作费用,大连新青年网站,五年四班里的视频怎样下载啊?  网站制作壁纸教程视频,电脑壁纸网站?  Laravel怎么进行数据库回滚_Laravel Migration数据库版本控制与回滚操作  Laravel中的withCount方法怎么高效统计关联模型数量  如何快速搭建高效可靠的建站解决方案?  如何在阿里云虚拟服务器快速搭建网站?  javascript和jQuery中的AJAX技术详解【包含AJAX各种跨域技术】  如何在云服务器上快速搭建个人网站?  作用域操作符会触发自动加载吗_php类自动加载机制与::调用【教程】  Laravel如何使用Spatie Media Library_Laravel图片上传管理与缩略图生成【步骤】  哪家制作企业网站好,开办像阿里巴巴那样的网络公司和网站要怎么做?  Laravel怎么配置自定义表前缀_Laravel数据库迁移与Eloquent表名映射【步骤】  阿里云网站搭建费用解析:服务器价格与建站成本优化指南  Python并发异常传播_错误处理解析【教程】  Laravel如何处理跨站请求伪造(CSRF)保护_Laravel表单安全机制与令牌校验  HTML5空格在Angular项目里怎么处理_Angular中空格的渲染问题【详解】  深圳防火门网站制作公司,深圳中天明防火门怎么编码?  JavaScript如何实现音频处理_Web Audio API如何工作?  大型企业网站制作流程,做网站需要注册公司吗?