-
2018-09-12 11:48:43
两层循环实现建树
-
创建节点类
public class TreeNode {
protected int id;
protected int parentId;
protected List<TreeNode> children = new ArrayList<>();public void add(TreeNode node) {
children.add(node);
}
}-
建树实现
/**
* 两层循环实现建树
*
* @param treeNodes 传入的树节点列表
* @return
*/
public static <T extends TreeNode> List<T> bulid(List<T> treeNodes, Object root) {List<T> trees = new ArrayList<T>();
for (T treeNode : treeNodes) {
if (root.equals(treeNode.getParentId())) {
trees.add(treeNode);
}for (T it : treeNodes) {
if (it.getParentId() == treeNode.getId()) {
if (treeNode.getChildren() == null) {
treeNode.setChildren(new ArrayList<TreeNode>());
}
treeNode.add(it);
}
}
}
return trees;
}递归方法建树
-
创建节点类(同上)
-
建树实现
/** * 使用递归方法建树 * * @param treeNodes * @return */ public static <T extends TreeNode> List<T> buildByRecursive(List<T> treeNodes, Object root) { List<T> trees = new ArrayList<T>(); for (T treeNode : treeNodes) { if (root.equals(treeNode.getParentId())) { trees.add(findChildren(treeNode, treeNodes)); } } return trees; }
更多相关内容 -
-
基于JAVA建立树形结构的算法优化.pdf
2021-07-02 19:02:54基于JAVA建立树形结构的算法优化.pdf -
建树代码 Java
2014-05-13 18:23:44// JAVA 新建 一个树的源代码 package com.xiangxiang.frame; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Vector; -
二叉树之建树和七种遍历(含Java代码)
2019-11-19 10:23:55在刷LeetCode的过程中,想把二叉树的一系列常用操作做一个整理,这篇文章总结了通过Java实现二叉树的创建树、层序遍历、递归和非递归的前中后遍历。二叉树的建树和七种遍历(含Java代码)
详细代码请访问我的github:二叉树操作
二叉树结点定义
一个树结点最基本的字段就是三个字段,分别代表该结点的值和它的左右孩子结点。
public class TreeNode { int val;//该结点的值 TreeNode left;//结点的左孩子结点 TreeNode right;//结点的右孩子结点 TreeNode(int x) {//构造方法 val = x; } }
创建二叉树
将下图的二叉树从上至下、从左至右存放在一个一维数组中,对应的一维数组为[1,2,3,4,5,6,7,8,9,10]。
可以明显看出在数组中下标为i的元素所对应的结点的左右结点在数组中的下标为2i+1和2i+2。因此,给定一个数组,我们可以从第一个元素开始递归创建二叉树。
public TreeNode buildTree(int[] nums, int i){ if(nums.length==0) return null; if(i>=nums.length) return null; TreeNode root = new TreeNode(nums[i]); root.left = buildTree(nums,2*i+1); root.right = buildTree(nums,2*i+2); return root; }
其中nums是给定的数组,i初始下标从0开始,返回值是一个树结点。首先创建值为nums[i]的结点,也是buildTree返回的树结点。从上图的结论易知其左右孩子结点的位置分别为2i+1=1和2i+2=2,因此使其左右结点分别指向buildTree(nums,2i+1)和root.right = buildTree(nums,2i+2)返回的树结点,通过递归创建二叉树。
二叉树的层序遍历
所谓层序遍历:即从上到下、从左至右依次遍历二叉树。
可以借助一个队列,通过队列先进先出的特点,首先将根结点放入队列,只要队列不空,就从队列中取出一个结点,再依次将其左右结点放入队列。由于每次都是父结点出队列后,子结点才进队列,而且是保持先左后右的顺序,所以能保证对树的遍历是从上到下、从左至右的依次遍历。
public void levelOrder(TreeNode root){ if(root==null) return; Queue<TreeNode> queue = new LinkedList<>(); queue.offer(root); while(!queue.isEmpty()){ TreeNode node = queue.poll(); System.out.print(node.val+ " "); if(node.left!=null) queue.offer(node.left); if(node.right!=null) queue.offer(node.right); } }
结合创建二叉树和层序遍历二叉树,在主类中测试:
int[] nums = {1,2,3,4,5,6,7,8,9,10}; BinaryTree tree = new BinaryTreeImpl(); //创建二叉树 TreeNode root = tree.buildTree(nums,0); System.out.println("二叉树的层序遍历"); tree.levelOrder(root);//结果输出为:1 2 3 4 5 6 7 8 9 10
二叉树的先序遍历
先序遍历是指:先访问根结点,再依次访问其左右结点。可以使用两种方式实现二叉树的先序遍历:递归遍历和非递归遍历。
递归遍历
递归方法的参数是一个树结点,开始时是树的根结点。如果该结点为null,则回到上一层结点,否则输出该结点的值,然后先遍历其左子树,再遍历其右子树。public void preOrder(TreeNode root){ if(root==null) return; System.out.print(root.val+" "); preOrder(root.left); preOrder(root.right); }
非递归遍历
在计算机中,对递归方法的调用是通过栈实现的。如果不使用递归方式,由程序员自己创建一个栈就能通过非递归方式实现先序遍历。public void preNonrecursion(TreeNode root) { if(root!=null){ Stack<TreeNode> stack = new Stack<>(); stack.push(root); while(!stack.empty()){ TreeNode t = stack.pop(); System.out.print(t.val+" "); if(t.right!=null) stack.push(t.right); if(t.left!=null){ stack.push(t.left); } } } }
由于递归是先进后出,所以进栈时右结点先进栈,然后左节点再进栈。
二叉树的中序遍历
中序遍历是指:先访问左子树(结点),再访问根结点,最后再访问右子树(结点)。
public void inOrder(TreeNode root){ if(root==null) return; inOrder(root.left); System.out.print(root.val + " "); inOrder(root.right); }
类似的,根据先序遍历的非递归实现,我们也可以实现中序遍历的非递归实现。
public void inNonrecursion(TreeNode root) { if(root!=null){ Stack<TreeNode> stack = new Stack<>(); TreeNode q = root; while(!stack.empty()||q!=null){ while(q!=null){ stack.push(q); q=q.left; } if(!stack.empty()){ q=stack.pop(); System.out.print(q.val+" "); q=q.right; } } } }
从代码中可以看出每一次根结点都在左节点进栈前进栈,等输出该结点值之后,其右节点才进栈,因此每一个结点的上一个输出结点要么是其左节点,要么为null不输出值。
二叉树的后序遍历
后序遍历是指:先依次访问左右结点,最后访问根结点。
类似于先序和中序遍历,我们可以写出后序遍历的递归和非递归方法。
递归方法
public void postOrder(TreeNode root){ if(root==null) return; postOrder(root.left); postOrder(root.right); System.out.print(root.val + " "); }
非递归方法
与先序遍历和中序遍历的非递归操作不同,因为在后序遍历中,要保证左孩子和右孩子都已被访问并且左孩子在右孩子前访问才能访问根结点,这里我借助了两个栈。public void postNonrecursion(TreeNode root) { if(root!=null){ Stack<TreeNode> stack1 = new Stack<>(); Stack<TreeNode> stack2 = new Stack<>(); TreeNode q = null; stack1.push(root); while(!stack1.empty()){ q=stack1.pop(); stack2.push(q); if(q.left!=null) stack1.push(q.left); if(q.right!=null) stack1.push(q.right); } while(!stack2.empty()){ q = stack2.pop(); System.out.print(q.val+" "); } } }
由于根结点是最后访问的,所以每次从stack1中取出结点后压入stack2,再将其左右结点依次压入stack1,等stack1中的元素都压入stack2之后,从stack2中依次出栈访问结点。
-
JAVA实现通过中序遍历和后序遍历序列建树,并求树的高度,用层次遍历做验证
2021-03-14 13:24:05作为例子的树长这样:package bstpractice;import java.util.ArrayList;...public class BstTest {public static void main(String args[]){//step1,先根据中序,后序序列建树List posOrder = ...作为例子的树长这样:
package bstpractice;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class BstTest {
public static void main(String args[]){
//step1,先根据中序,后序序列建树
List posOrder = Arrays.asList('B', 'A', 'E', 'D', 'C');
List inOrder = Arrays.asList('A', 'B', 'C', 'D', 'E');
System.out.println("通过");
System.out.println("中序序列:"+inOrder);
System.out.println("后序序列:"+posOrder);
System.out.println("成功构建二叉树,其先序遍历为:");
//建树
MyBinarySearchTree myBST =MyBinarySearchTree.buildTree(inOrder,posOrder);
//先序遍历
// System.out.println("先序遍历结果:");
System.out.println(myBST.preOrder());
System.out.println("高度是:"+myBST.getHigh());
System.out.println("通过其层次遍历:");
System.out.println(myBST.levelOrder());
System.out.println("可知正确");
}
}
package bstpractice;
import sun.reflect.generics.tree.Tree;
import java.util.*;
public class MyBinarySearchTree> {
public TreeNode root;
private int size;
private int high;
private class TreeNode {
TreeNode left;
TreeNode right;
E value;
public TreeNode(E value) {
this.value = value;
}
}
//中序、后序遍历建树方法
public static > MyBinarySearchTree buildTree(List inOrder, List posOrder) {
MyBinarySearchTree tree = new MyBinarySearchTree<>();
tree.size = 0;
tree.root = tree.build(inOrder, posOrder);
return tree;
}
private TreeNode build(List inOrder, List posOrder) {
//边界条件
if (posOrder.isEmpty() || posOrder == null) return null;
//if(inOrder.isEmpty()|| inOrder == null) return null;
E e = posOrder.get(posOrder.size() - 1);//根元素
int index = inOrder.indexOf(e);//得到划分位置和 左子树子序列长度信息,是index!!不是index-1
TreeNode node = new TreeNode(e);
//inOrder(0,index-1);index;(index+1,size-1)
//posOrder(0,0+index-1);(index,size-2);size-1;
//subList【 )!!! subList【 )!!! subList【 )!!! subList【 )!!!
List subLeftInOrder = inOrder.subList(0, index); //实际[0,index-1];
List subLeftPosOrder = posOrder.subList(0, index);
node.left = build(subLeftInOrder, subLeftPosOrder);
List subRightInOrder = inOrder.subList(index + 1, posOrder.size());//可不是size-1 ; size 是树的大小信息...;左闭右开
List subRightPosOrder = posOrder.subList(index, posOrder.size() - 1);
node.right = build(subRightInOrder, subRightPosOrder);
return node;
}
//用栈实现层次遍历,实现方式有多种,就用上课老师讲的反式实现吧;大致思路就是用一个size记录一层的大小,集中手机层次的结点
/* 算法:
1.入栈根结点
2.队列空?
不是:
a.查看队列的大小,记为size;
b.循环控制出队列size个元素
1).出结点并访问(添加到list)
2).出结点有左子树?有左结点入队列
3).出结点有右子树?有右节点入队列
返回回size个元素的Linkedlist到res中
c.回到2
是:返回res列表(List),res的元素是Linkedlist
* */
public List> levelOrder(){
List> res = new ArrayList<>();
if(root == null) return null;
Queue queue = new LinkedList<>(); //queue 必须用LinkedList,才有继承Queue接口
queue.add(root);
while(!queue.isEmpty()){
int count = queue.size();
List oneLevelList = new ArrayList<>();
while(count>0){
TreeNode p = queue.remove();
oneLevelList.add((E) p.value);
count --;
if(p.left!=null) queue.add(p.left);
if(p.right!=null) queue.add(p.right);
}
res.add(oneLevelList);
}
return res;
}
//返回高度的方法
public int getHigh(){
if(root == null) return 0;
return high = high(root);
}
private int high(TreeNode p){ //求树的高度,等于左子树和右子树高度之中较大的那个
int leftH =0;
int rightH =0;
//没有子树了
if(p.left == null && p.right == null){
return 1;
}
//有左子树,递归求左子树给高度
if(p.left !=null) {
leftH = high(p.left)+1;
}
//有右子树,递归求右子树高度
if(p.right != null){
rightH = high(p.right)+1;
}
return leftH >= rightH ? leftH : rightH ;
}
//先实现一个递归先序遍历,NLR
public List preOrder() {
List list = new ArrayList<>();
preOrder(root, list);
return list;
}
private void preOrder(TreeNode scan, List list) {
if (scan == null) return;
list.add((E) scan.value);
preOrder(scan.left, list);
preOrder(scan.right, list);
}
}
在IDEA中运行结果:
注意事项:在实现建树的时候,要记得subList的参数是左闭右开的
-
Java实现的二叉树常用操作【前序建树,前中后递归非递归遍历及层序遍历】
2021-02-27 08:31:53本文实例讲述了Java实现的二叉树常用操作。分享给大家供大家参考,具体如下:import java....//二叉树的建树,前中后 递归非递归遍历 层序遍历//Node节点class Node {int element;Node left;Node right;public Nod...本文实例讲述了Java实现的二叉树常用操作。分享给大家供大家参考,具体如下:
import java.util.ArrayDeque;
import java.util.Queue;
import java.util.Stack;
//二叉树的建树,前中后 递归非递归遍历 层序遍历
//Node节点
class Node {
int element;
Node left;
Node right;
public Node() {
}
public Node(int element) {
this.element = element;
}
}
// BinaryTree
public class Tree {
// creat tree from array
public static Node creatTree(int[] data, int i) {
if (i >= data.length || data[i] == -1)
return null;
Node temp = new Node(data[i]);
temp.left = creatTree(data, i * 2 + 1);
temp.right = creatTree(data, i * 2 + 2);
return temp;
}
// pre前序遍历递归
public static void pre(Node temp) {
if (temp == null)
return;
System.out.print(temp.element + " ");
pre(temp.left);
pre(temp.right);
}
// mid中序遍历递归
public static void mid(Node temp) {
if (temp == null)
return;
mid(temp.left);
System.out.print(temp.element + " ");
mid(temp.right);
}
// last后序遍历递归
public static void last(Node temp) {
if (temp == null)
return;
last(temp.left);
last(temp.right);
System.out.print(temp.element + " ");
}
// pre1前序遍历非递归
public static void pre1(Node temp) {
Stack stack = new Stack<>();
while (temp != null || !stack.isEmpty()) {
while (temp != null) {
stack.push(temp);
System.out.print(temp.element + " ");
temp = temp.left;
}
if (!stack.isEmpty()) {
temp = stack.pop().right;
}
}
}
// mid1中序遍历非递归
public static void mid1(Node temp) {
Stack stack = new Stack<>();
while (temp != null || !stack.isEmpty()) {
while (temp != null) {
stack.push(temp);
temp = temp.left;
}
if (!stack.isEmpty()) {
temp = stack.pop();
System.out.print(temp.element + " ");
temp = temp.right;
}
}
}
// last1后序遍历非递归
public static void last1(Node temp) {
Stack stack = new Stack<>();
Stack stack2 = new Stack<>();
while (temp != null || !stack.isEmpty()) {
while (temp != null) {
stack.push(temp);
stack2.push(temp);
temp = temp.right;
}
if (!stack.isEmpty()) {
temp = stack.pop().left;
}
}
while (!stack2.isEmpty())
System.out.print(stack2.pop().element + " ");
}
// ceng层序遍历
public static void ceng(Node temp) {
if (temp == null)
return;
Queue queue = new ArrayDeque<>();
queue.offer(temp);
while (!queue.isEmpty()) {
temp = queue.poll();
System.out.print(temp.element + " ");
if (temp.left != null)
queue.offer(temp.left);
if (temp.right != null)
queue.offer(temp.right);
}
}
// Demo
public static void main(String[] args) {
int[] array = { 1, 2, 3, 4, 5, 6, 7, -1, -1, 10, -1, -1, 13 };
Node tree = creatTree(array, 0);
System.out.println("脚本之家测试结果:");
pre(tree);
System.out.println();
pre1(tree);
System.out.println();
mid(tree);
System.out.println();
mid1(tree);
System.out.println();
last(tree);
System.out.println();
last1(tree);
System.out.println();
ceng(tree);
}
}
运行结果:
希望本文所述对大家java程序设计有所帮助。
-
Java、二叉树(泛型)
2021-11-18 16:40:02本程序实现了泛型的二叉树及其相关操作。 相关操作:遍历(广义表表示法、先序遍历、中序遍历、后序遍历);...import java.util.ArrayList; import java.util.LinkedList; public class Bina... -
java 实现的二叉树前序建树,中序建树,后序建树以及前序遍历,中序遍历和后序遍历的代码
2022-01-20 00:47:59java 实现的二叉树前序建树,中序建树,后序建树以及前序遍历,中序遍历和后序遍历的代码 -
Java 递归建树
2021-01-27 18:17:37} Mapper层 select * from t_tree Service层 //递归建树 List handleTree(); ServiceImpl层 @Service public class TreeServiceImpl implements TreeService { @Resource private TreeDao treeDao; @Override ... -
Java创建树形数据结构
2021-09-17 10:54:12Java 树形结构的创建一、使用Java创建 “前缀树(字典树)” 一、使用Java创建 “前缀树(字典树)” Java 中没有C语言中的指针,我们创建树形结构的时候可以使用Map集合来进行创建 Trie trie = new Trie(); //... -
java简易版开心农场源码-blog:建树进口
2021-06-05 10:15:14java简易版开心农场源码 20180320 最近集中将代码迁移到github,顺便将blog也逐步迁移过来,平时较忙,除了感觉有些创新的,写的文章也很少 国内git带宽怎么这么低啊,图片都显示不粗来~~~ 20180410 今天听闻Android... -
手把手教你用Java代码画二叉树
2020-12-11 14:17:46import java.awt.image.BufferedImage; import java.io.FileOutputStream; import java.io.IOException; public class Drawing { // 以下是常量 private static final String PATH = "F:/tree.png"; // ... -
树:Java中树的构建
2020-04-30 08:00:38很多初学的小伙伴都不知道如何在Java中自定义树结构,今天它来了,Java的核心就是面向对象编程,因此我们可以把树看成一个对象,直接上代码。 树的构建 public class TreeNode { int val; TreeNode left; ... -
java写的递归建树型结构
2009-06-18 13:03:27java写的从数据库中提取数据,用变量创建树型结构 -
Java使用泛型递归构建树
2020-08-22 17:02:13public class TreeUtil { /** * 使用递归方法建树 * * @param modules * @return */ public static <T> List<Tree<T>> buildByRecursive(List<Tree<T>> modules, String pId) { List<Tree<T>> trees = new ... -
JAVA 快速构建树形结构
2021-06-01 12:06:20JDK 1.8+ Node 中pid 为 0 的是根节点 -
[Leetcode] Construct Binary Tree from Traversal 根据遍历序列建树
2021-03-06 15:08:01Construct Binary Tree from Preorder and Inorder TraversalGiven preorder and inorder traversal of a tree, construct the binary tree.二分法复杂度时间 O(N^2) 空间 O(N)思路我们先考察先序遍历序列和中序遍历... -
二叉树(从建树、遍历到存储)Java
2019-10-28 17:46:25五、完整代码 这是我在学习过程中模仿Java集合类写的一个二叉树类,以Integer类为例,如果引入泛型的话,所有类都可以,欢迎大家指导。 BinaryTree类: import java.util.LinkedList; public class BinaryTree { /... -
在java中创建树数据结构?
2021-03-08 19:08:05我试图在java中创建一个树数据结构,其中每个父节点只能有三个子节点,但在节点至少有一个子节点但少于3个子节点的情况下,我一直坚持在树上添加一个节点.我不确定是否应该使用迭代器来迭代我当前节点的节点列表.我试着... -
解析Java实现二叉树前序建树,前中后递归非递归遍历及层序遍历
2021-03-09 17:02:54Java实现的二叉树常用操作【前序建树,前中后递归非递归遍历及层序遍历】本文实例讲述了Java实现的二叉树常用操作。分享给大家供大家参考,具体如下:import java.util.ArrayDeque;import java.util.Queue;import ... -
二叉树的建树、遍历(先序、中序、后序、层次)(递归和非递归)--Java实现
2021-04-15 19:27:18public class BinaryTree {private static class Node{public E value; //节点值public Node left; //左节点public Node right;//右节点public Node(E value) {this.value = value;this.left = null;... -
Maven——Java项目构建工具
2016-05-02 16:27:41Java中项目管理与构建工具,目前有Ant,Maven,Gradle工具。没有这些工具,也可以做开始,但是会增大开发量,我本人也是实际工作中接触到了项目构建工具,才感受到构建工具的好处。在我做的第一个项目总就是用的ant... -
Java_ArticleTree例题树>
2018-04-30 02:45:18import java.sql.*; //jdbc.jar public class ArticleTree { public static void main(String[] args) { new ArticleTree().show(); } //方法show,显示建立的树 public void show() { Connection conn = null; ... -
二叉树的建树
2021-03-15 00:05:45#include #include #include #include #include #include#includeusing namespace std;char s[100000];int flog=0;struct tree{char a;struct tree *left,*right;}*head;tree * great(){char k;... -
前序加中序 建树 推出后序 中序加后序建树推出前序 java建立文件
2019-08-15 22:12:32前序加中序建树 找到根节点 creat(&t->left,p1+1,p1+root-m1,m1,root-1);每次找到递归出的俩个数组部分中的父节点 creat(&t->right,p1+root-m1+1,p2,root+1,m2); 后序加中序差不多 装java装了一晚上 ...