导航:首页 > 编程语言 > java递归生成树

java递归生成树

发布时间:2022-12-21 10:08:06

java 递归数据库生成 树形结构问题

1、准备表结构及对应的表数据
a、表结构:
create table TB_TREE
(
CID NUMBER not null,
CNAME VARCHAR2(50),
PID NUMBER //父节点
)

b、表数据:

insert into tb_tree (CID, CNAME, PID) values (1, '中国', 0);
insert into tb_tree (CID, CNAME, PID) values (2, '北京市', 1);
insert into tb_tree (CID, CNAME, PID) values (3, '广东省', 1);
insert into tb_tree (CID, CNAME, PID) values (4, '上海市', 1);
insert into tb_tree (CID, CNAME, PID) values (5, '广州市', 3);
insert into tb_tree (CID, CNAME, PID) values (6, '深圳市', 3);
insert into tb_tree (CID, CNAME, PID) values (7, '海珠区', 5);
insert into tb_tree (CID, CNAME, PID) values (8, '天河区', 5);
insert into tb_tree (CID, CNAME, PID) values (9, '福田区', 6);
insert into tb_tree (CID, CNAME, PID) values (10, '南山区', 6);
insert into tb_tree (CID, CNAME, PID) values (11, '密云县', 2);
insert into tb_tree (CID, CNAME, PID) values (12, '浦东', 4);

2、TreeNode对象,对应tb_tree

public class TreeNode implements Serializable {
private Integer cid;
private String cname;
private Integer pid;
private List nodes = new ArrayList();

public TreeNode() {
}

//getter、setter省略
}

3、测试数据

public class TreeNodeTest {
@Test
public void loadTree() throws Exception{
System.out.println(JsonUtils.javaToJson(recursiveTree(1)));
}

/**
* 递归算法解析成树形结构
*
* @param cid
* @return
* @author jiqinlin
*/
public TreeNode recursiveTree(int cid) {
//根据cid获取节点对象(SELECT * FROM tb_tree t WHERE t.cid=?)
TreeNode node = personService.getreeNode(cid);
//查询cid下的所有子节点(SELECT * FROM tb_tree t WHERE t.pid=?)
List childTreeNodes = personService.queryTreeNode(cid);
//遍历子节点
for(TreeNode child : childTreeNodes){
TreeNode n = recursiveTree(child.getCid()); //递归
node.getNodes().add(n);
}

return node;
}
}

输出的json格式如下:

{
"cid": 1,
"nodes": [
{
"cid": 2,
"nodes": [
{
"cid": 11,
"nodes": [

],
"cname": "密云县",
"pid": 2
}
],
"cname": "北京市",
"pid": 1
},
{
"cid": 3,
"nodes": [
{
"cid": 5,
"nodes": [
{
"cid": 7,
"nodes": [

],
"cname": "海珠区",
"pid": 5
},
{
"cid": 8,
"nodes": [

],
"cname": "天河区",
"pid": 5
}
],
"cname": "广州市",
"pid": 3
},
{
"cid": 6,
"nodes": [
{
"cid": 9,
"nodes": [

],
"cname": "福田区",
"pid": 6
},
{
"cid": 10,
"nodes": [

],
"cname": "南山区",
"pid": 6
}
],
"cname": "深圳市",
"pid": 3
}
],
"cname": "广东省",
"pid": 1
},
{
"cid": 4,
"nodes": [
{
"cid": 12,
"nodes": [

],
"cname": "浦东",
"pid": 4
}
],
"cname": "上海市",
"pid": 1
}
],
"cname": "中国",
"pid": 0
}

㈡ 求Java List 递归算法..

无需JAVA递归取!

从设计角度看,表结构设计已经有问题了!
即使是树状结构,为何表结构没有体现?这也构成了为何楼主需要想办法来应对非树状结构数据的树状显示问题。

先进一步来说,表加一个grade字段,来表明当前记录处于第几级。那么直接一个SQL就可以取出来:
select lpad(' ',a.grade,'-')||a.name from myList a
这样就可以按楼主需要的结构取出数据;

但还存在一个问题,就是顺序问题,这样取出的数据是无序的!

那么我们再进一步看,我在做这种数据结构的表设计时,往往会给每个结点增加两个字段,left/right,分别代表其在树中的左右值。

这样就可以在上面SQL后增加order by a.left以保证取出数据的顺序。

㈢ 求助在java里实现树形目录

给你一个读取目录结构,生成字符串的程序参考一下吧。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileFilter;
import java.util.HashMap;
import java.util.Map;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;

public class PathTree extends JPanel {
private static final long serialVersionUID = 1L;

private JButton stopButton = new JButton("停止扫描");
private JButton browseButton = new JButton("选择文件夹");
private JTextArea pathsTextArea = new JTextArea();
private JCheckBox showHiddenFilesCheckbox = new JCheckBox("显示隐藏文件", false);

private Map<Integer, String> pathIndexes = new HashMap<Integer, String>();
private FileFilter docFilter = new DocFilter(); // 文档过滤器
private FileFilter dirFilter = new DirFilter(); // 文件夹过滤器

private boolean stopped = false; // 是否停止扫描的标志

public PathTree() {
initGui();
}

// 初始化界面
private void initGui() {
this.setLayout(new BorderLayout());

JPanel buttonsPanel = new JPanel();
buttonsPanel.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, Color.GRAY));
buttonsPanel.add(showHiddenFilesCheckbox);
buttonsPanel.add(browseButton);
buttonsPanel.add(stopButton);
this.add(buttonsPanel, BorderLayout.NORTH);

JScrollPane scroller = new JScrollPane(pathsTextArea);
scroller.setBorder(null);
this.add(scroller, BorderLayout.CENTER);

browseButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// 选择文件夹
final JFileChooser chooser = new JFileChooser();
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int result = chooser.showOpenDialog(PathTree.this);

if (result == JFileChooser.APPROVE_OPTION) {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
File dir = chooser.getSelectedFile();
pathsTextArea.setText("");
stopped = false;
walkTree(dir, 0);
}
});
t.start();
}
}
});

stopButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
stopped = true;
}
});
}

// 递归遍历目录树
private void walkTree(File dir, int level) {
// 1. current dir path
// 2. docs path that located in this dir
// 3. sub dirs path

if (stopped) { return; }

// 如果不显示隐藏文件,则返回
if (dir.isHidden() && !showHiddenFilesCheckbox.isSelected()) { return; }

final StringBuilder pathBuffer = new StringBuilder(1024);

// 访问当前目录
pathBuffer.append(createPath(dir, level));

// 访问文档
for (File doc : dir.listFiles(docFilter)) {
if (doc.isHidden() && !showHiddenFilesCheckbox.isSelected()) {
continue;
}
pathBuffer.append(createPath(doc, level + 1));
}

// 把当前目录下的文件更新到text area中
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
pathsTextArea.append(pathBuffer.toString());
}
});

// 递归遍历子目录
for (File subDir : dir.listFiles(dirFilter)) {
walkTree(subDir, level + 1);
}
}

// 创建文件的路径
public String createPath(File file, int level) {
StringBuilder pathBuffer = new StringBuilder(128);
pathBuffer.append(getPathIndex(level)).append(file.getName()).append("\n");

return pathBuffer.toString();
}

// 创建目录的缩进
private String getPathIndex(int level) {
// 如果不存在,则创建
if (pathIndexes.get(level) == null) {
StringBuilder indexBuffer = new StringBuilder(128);
for (int i = 0; i < level; ++i) {
indexBuffer.append("| ");
}

indexBuffer.append("|----");
pathIndexes.put(Integer.valueOf(level), indexBuffer.toString());
return indexBuffer.toString();
} else {
return pathIndexes.get(level);
}
}

// 创建主窗口
private static void createGUIAndShow() {
JFrame frame = new JFrame("目录结构树");
frame.setContentPane(new PathTree());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

Dimension ss = Toolkit.getDefaultToolkit().getScreenSize();
int w = 600;
int h = 700;
int x = (ss.width - w) / 2;
int y = (ss.height - h) / 2 - 40;
x = x > 0 ? x : 0;
y = y > 0 ? y : 0;
frame.setBounds(x, y, w, h);
frame.setVisible(true);
}

public static void main(String[] args) {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
//UIManager.setLookAndFeel("com.seaglasslookandfeel.SeaGlassLookAndFeel");
} catch (Exception e) {
e.printStackTrace();
}

SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
createGUIAndShow();
}
});
}
}

class DocFilter implements FileFilter {
@Override
public boolean accept(File file) {
return file.isFile();
}
}

class DirFilter implements FileFilter {
@Override
public boolean accept(File file) {
return file.isDirectory();
}
}

这是生成的目录树结构:
|----Desktop
| |----3D数学基础_图形与游戏开发.pdf
| |----Hibernate与IBatis的优缺点及可行性分析2.txt
| |----Hibernate和iBatis比较.txt
| |----深入理解O:R Mapping - Hibernate - Java - JavaEye论坛.webarchive
| |----地下管线安全管理系统
| | |----创造三大价值,让收益更加显着1_resize.jpg
| | |----创造三大价值,让收益更加显着_resize.jpg
| | |----永安集成管理系统_resize.jpg
| | |----系统实现流程_resize.jpg
| | |----自主创新,于创新中超越_resize.jpg
| | |----行业领先功能,解决四大问题_resize.jpg
| | |----解决地下管线行业难题_resize.jpg

㈣ Java数据结构二叉树深度递归调用算法求内部算法过程详解

二叉树
1
2 3
4 5 6 7
这个二叉树的深度是3,树的深度是最大结点所在的层,这里是3.

应该计算所有结点层数,选择最大的那个。

根据上面的二叉树代码,递归过程是:

f(1)=f(2)+1 > f(3) +1 ? f(2) + 1 : f(3) +1

f(2) 跟f(3)计算类似上面,要计算左右结点,然后取大者

所以计算顺序是f(4.left) = 0, f(4.right) = 0

f(4) = f(4.right) + 1 = 1

然后计算f(5.left) = 0,f(5.right) = 0

f(5) = f(5.right) + 1 =1

f(2) = f(5) + 1 =2

f(1.left) 计算完毕,计算f(1.right) f(3) 跟计算f(2)的过程一样。

得到f(3) = f(7) +1 = 2

f(1) = f(3) + 1 =3

if(depleft>depright){
returndepleft+1;
}else{
returndepright+1;
}

只有left大于right的时候采取left +1,相等是取right

㈤ java使用递归实现树形结构


inserttb_menu(id,name,parent)(640000000000,北京市,0);
inserttb_menu(id,name,parent)(640100000000,昌平区,1);
inserttb_menu(id,name,parent)(640101000000,霍营,2);
inserttb_menu(id,name,parent)(640101001000,回龙观东大街,3);

添加一个节点属性, 根据数据不同代表的地位不同,0就代表父节点 ,1是0的子节点,2是1的子节点,以此类推。

㈥ java怎么递归出一棵树来,表结构为 int id,int pid,varchar text,varchar url,

要递归树结构必须要层级关系。你给的字段是什么表示?

㈦ java 怎么把数据库 ID PID(父ID) NAME 三个字段 数据递归处理成树形结构 首ID的PID为0

  1. 如果数据库是oracle,可以用递归的sql实现

  2. 如果想用java实现

    第一步遍历节点放入map结构

    再次遍历节点,取出当前节点的父节点,parentNode.setchild(courrentNode)
    这样第二次遍历完后已经是树形结构了。

  3. 从map中取出root节点就行

㈧ 如何用Java实现树形结构啊

定义一个简单的菜单类 这里是简单的示例 你可以自行扩展package entity;import java.util.ArrayList;
import java.util.List;/**
* 菜单类
* @author Administrator
*
*/
public class Menu {
/**
* 菜单标题
*/
private String title;
/**
* 子菜单的集合
*/
private List<Menu> childs;

/**
* 父菜单
*/
private Menu parent;

/**
* 构造函数 初始化标题和子菜单集合
*/
public Menu(String title) {
this();
this.title=title;
}
/**
* 构造函数 创建一个虚拟的父菜单(零级菜单) 所有的一级菜单都归属于一个虚拟的零级菜单
*
*/
public Menu() {
this.childs = new ArrayList<Menu>();
}
/**
* 获取子菜单
* @return
*/
public List<Menu> getChilds() {
return childs;
}
/**
* 获取标题
* @return
*/
public String getTitle() {
return title;
}
/**
* 获取父菜单
* @return
*/
public Menu getParent() {
return parent;
}
/**
* 添加子菜单并返回该子菜单对象
* @param child
* @return
*/
public Menu addChild(Menu child){
this.childs.add(child);
return child;
}
/**
* 设置父菜单
* @param parent
*/
public void setParent(Menu parent) {
this.parent = parent;
}
/**
* 设置标题
* @param title
*/
public void setTitle(String title) {
this.title = title;
}
} 测试package entity;
/**
* 测试类
* @author Administrator
*
*/
public class Test { /**
* @param args
*/
public static void main(String[] args) {
/**
* 创建一个虚拟的父菜单 用于存放一级菜单 menu01 和 menu02
*/
Menu root = new Menu();
/**
* 创建两个一级菜单
*/
Menu menu01 = new Menu("一级菜单01");
Menu menu02 = new Menu("一级菜单02");
/**
* 加入虚拟菜单
*/
root.addChild(menu01);
root.addChild(menu02);
/**
* 为两个一级菜单分别添加两个子菜单 并返回该子菜单 需要进一步处理的时候 才接收返回的对象 否则只要调用方法
*/
Menu menu0101 = menu01.addChild(new Menu("二级菜单0101"));
menu01.addChild(new Menu("二级菜单0102"));
menu02.addChild(new Menu("二级菜单0201"));
Menu menu0202 = menu02.addChild(new Menu("二级菜单0202"));
/**
* 添加三级菜单
*/
menu0101.addChild(new Menu("三级菜单010101"));
menu0202.addChild(new Menu("三级菜单020201"));
/**
* 打印树形结构
*/
showMenu(root);
} /**
* 递归遍历某个菜单下的菜单树
*
* @param menu
* 根菜单
*/
private static void showMenu(Menu menu) {
for (Menu child : menu.getChilds()) {
showMenu(child, 0);
}
} private static void showMenu(Menu menu, int tabNum) {
for (int i = 0; i < tabNum; i++)
System.out.print("\t");
System.out.println(menu.getTitle());
for (Menu child : menu.getChilds())
// 递归调用
showMenu(child, tabNum + 1);
}}
控制台输出结果 一级菜单01 二级菜单0101
三级菜单010101
二级菜单0102一级菜单02
二级菜单0201
二级菜单0202
三级菜单020201

㈨ 用java怎么构造一个二叉树呢

二叉树的相关操作,包括创建,中序、先序、后序(递归和非递归),其中重点的是java在先序创建二叉树和后序非递归遍历的的实现。
package com.algorithm.tree;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Queue;
import java.util.Scanner;
import java.util.Stack;
import java.util.concurrent.LinkedBlockingQueue;

public class Tree<T> {

private Node<T> root;

public Tree() {
}

public Tree(Node<T> root) {
this.root = root;
}

//创建二叉树
public void buildTree() {

Scanner scn = null;
try {
scn = new Scanner(new File("input.txt"));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
root = createTree(root,scn);
}
//先序遍历创建二叉树
private Node<T> createTree(Node<T> node,Scanner scn) {

String temp = scn.next();

if (temp.trim().equals("#")) {
return null;
} else {
node = new Node<T>((T)temp);
node.setLeft(createTree(node.getLeft(), scn));
node.setRight(createTree(node.getRight(), scn));
return node;
}

}

//中序遍历(递归)
public void inOrderTraverse() {
inOrderTraverse(root);
}

public void inOrderTraverse(Node<T> node) {
if (node != null) {
inOrderTraverse(node.getLeft());
System.out.println(node.getValue());
inOrderTraverse(node.getRight());
}
}

//中序遍历(非递归)
public void nrInOrderTraverse() {

Stack<Node<T>> stack = new Stack<Node<T>>();
Node<T> node = root;
while (node != null || !stack.isEmpty()) {
while (node != null) {
stack.push(node);
node = node.getLeft();
}
node = stack.pop();
System.out.println(node.getValue());
node = node.getRight();

}

}
//先序遍历(递归)
public void preOrderTraverse() {
preOrderTraverse(root);
}

public void preOrderTraverse(Node<T> node) {
if (node != null) {
System.out.println(node.getValue());
preOrderTraverse(node.getLeft());
preOrderTraverse(node.getRight());
}
}

//先序遍历(非递归)
public void nrPreOrderTraverse() {

Stack<Node<T>> stack = new Stack<Node<T>>();
Node<T> node = root;

while (node != null || !stack.isEmpty()) {

while (node != null) {
System.out.println(node.getValue());
stack.push(node);
node = node.getLeft();
}
node = stack.pop();
node = node.getRight();
}

}

//后序遍历(递归)
public void postOrderTraverse() {
postOrderTraverse(root);
}

public void postOrderTraverse(Node<T> node) {
if (node != null) {
postOrderTraverse(node.getLeft());
postOrderTraverse(node.getRight());
System.out.println(node.getValue());
}
}

//后续遍历(非递归)
public void nrPostOrderTraverse() {

Stack<Node<T>> stack = new Stack<Node<T>>();
Node<T> node = root;
Node<T> preNode = null;//表示最近一次访问的节点

while (node != null || !stack.isEmpty()) {

while (node != null) {
stack.push(node);
node = node.getLeft();
}

node = stack.peek();

if (node.getRight() == null || node.getRight() == preNode) {
System.out.println(node.getValue());
node = stack.pop();
preNode = node;
node = null;
} else {
node = node.getRight();
}

}

}

//按层次遍历
public void levelTraverse() {
levelTraverse(root);
}

public void levelTraverse(Node<T> node) {

Queue<Node<T>> queue = new LinkedBlockingQueue<Node<T>>();
queue.add(node);
while (!queue.isEmpty()) {

Node<T> temp = queue.poll();
if (temp != null) {
System.out.println(temp.getValue());
queue.add(temp.getLeft());
queue.add(temp.getRight());
}

}

}

}

//树的节点

class Node<T> {

private Node<T> left;
private Node<T> right;
private T value;

public Node() {
}
public Node(Node<T> left,Node<T> right,T value) {
this.left = left;
this.right = right;
this.value = value;
}

public Node(T value) {
this(null,null,value);
}
public Node<T> getLeft() {
return left;
}
public void setLeft(Node<T> left) {
this.left = left;
}
public Node<T> getRight() {
return right;
}
public void setRight(Node<T> right) {
this.right = right;
}
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}

}
测试代码:
package com.algorithm.tree;

public class TreeTest {

/**
* @param args
*/
public static void main(String[] args) {
Tree<Integer> tree = new Tree<Integer>();
tree.buildTree();
System.out.println("中序遍历");
tree.inOrderTraverse();
tree.nrInOrderTraverse();
System.out.println("后续遍历");
//tree.nrPostOrderTraverse();
tree.postOrderTraverse();
tree.nrPostOrderTraverse();
System.out.println("先序遍历");
tree.preOrderTraverse();
tree.nrPreOrderTraverse();

//
}

}

阅读全文

与java递归生成树相关的资料

热点内容
dvd光盘存储汉子算法 浏览:757
苹果邮件无法连接服务器地址 浏览:963
phpffmpeg转码 浏览:671
长沙好玩的解压项目 浏览:145
专属学情分析报告是什么app 浏览:564
php工程部署 浏览:833
android全屏透明 浏览:737
阿里云服务器已开通怎么办 浏览:803
光遇为什么登录时服务器已满 浏览:302
PDF分析 浏览:485
h3c光纤全工半全工设置命令 浏览:143
公司法pdf下载 浏览:382
linuxmarkdown 浏览:350
华为手机怎么多选文件夹 浏览:683
如何取消命令方块指令 浏览:350
风翼app为什么进不去了 浏览:778
im4java压缩图片 浏览:362
数据查询网站源码 浏览:150
伊克塞尔文档怎么进行加密 浏览:892
app转账是什么 浏览:163