数据表结构和简单的数据如下
         节点id                     父节点id                  节点名称
         tree_id                 sup_id                   tree_nm    
REW20060928121449 root                  欢迎大家参与评论
REW20061201115757 root                  "溃坝和三鹿奶粉事件"。
REW20061130163122 root                  美众议院否决财政部7000亿美元救市计划
REW20061201162951 root                  关于本论坛的3个问题
REW20060928125113 root                  请对本网站留下您宝贵的意见
PRH20061129110452 REW20060928121449 huihzh
PRH20061201115619 REW20061130163122 huihzh
PRH20061201115641 REW20061130163122 huihzh
PRH20061130162809 REW20060928125113 shu_di
PRH20060928121624 REW20060928121449 test
        PRH20060928121625 PRH20061201115619 zhao_xx
        PRH20060928121626 PRH20061201115619 zhang_ll
        。              。        。我想要生成如下的树结构:
root
    欢迎大家参与评论
         huihzh
        test
    "溃坝和三鹿奶粉事件"
    美众议院否决财政部7000亿美元救市计划
         huihzh
            zhao_xx
                .......(还可以有子节点)
                .......
            zhang_ll
        huihzh
    关于本论坛的3个问题
    请对本网站留下您宝贵的意见
         shu_di请高手多多指教,数据表中记录的顺序是无序的,记录可能会很多,需要一套很好的算法生成这个树结构。
如果这样的表结构不合理,可以修改表结构。
          

解决方案 »

  1.   

    楼主是要内存表现形式,还是要swing编程,还是要生成xml文档,还是要在web页面上显示?如果是数据结构方面,只要一个内存表现形式的话,编写2~3个类就可以实现了。swing编程里面,了解一下JTree相关的知识,就可以解决。生成xml,要看你有没有使用dom4j,jdom之类的插件,当然,也要根据情况编写一个处理方法。如果是在web页面上显示,那,应该是生成一个含有列表的div,逻辑上和生成xml差不多。
      

  2.   

    如果是web页面的话,没有什么框架里有能直接用的东西么,我觉得动态菜单树这种东西很常用,应该会有吧
      

  3.   

    VOimport java.util.ArrayList;public class Bom {
    private Bom parent;
    private ArrayList childs = new ArrayList();
    private String bom_no;
    private String prod_name;
    private String prod_no;
    public String getTopProdNo()
    {
    if(this.parent==null)
    {
    return this.getProd_no();
    }else
    {
    return this.getParent().getTopProdNo();
    }
    }
    public String getProd_no() {
    return prod_no;
    }
    public void setProd_no(String prod_no) {
    this.prod_no = prod_no;
    }
    public int getLevel()
    {
    if(this.parent==null)
    {
    return 1;
    }else
    {
    return this.getParent().getLevel()+1;
    }
    }
    public String getBom_no() {
    return bom_no;
    }
    public void setBom_no(String bom_no) {
    this.bom_no = bom_no;
    }
    public ArrayList getChilds() {
    return childs;
    }
    public void setChilds(ArrayList childs) {
    this.childs = childs;
    }
    public Bom getParent() {
    return parent;
    }
    public void setParent(Bom parent) {
    this.parent = parent;
    }
    public String getProd_name() {
    return prod_name;
    }
    public void setProd_name(String prod_name) {
    this.prod_name = prod_name;
    }

    }操作DAOimport java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;import com.szdzsoft.util.DBConnection;
    import com.szdzsoft.util.IDgen;
    import com.szdzsoft.util.Logger;public class BomUtil {
    private Bom bom;
    private DBConnection db = new DBConnection();
    private Connection conn ;
    public BomUtil()
    {
    //后台测试使用
    //conn = new TestConnection().getTestConnection();
    } /**
     * 根据一个Bom编号,查询出它的所有子Bom.
     * @param pid
     * @return
     */
    public Bom getAlls(String pid)
    {
    try {
    conn = db.makeConnection();
    Statement stmt = conn.createStatement();
    ResultSet rs = stmt.executeQuery("select bom_no,prod_no,prod_name from bs_bom where bom_no ='"+pid+"'");
    while(rs.next())
    {
    bom = new Bom();
    bom.setBom_no(pid);
    bom.setProd_no(rs.getString(2));
    bom.setProd_name(rs.getString(3));
    }
    if(bom!=null)
    {
    make(bom);
    }
    } catch (SQLException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    Logger.writeLog("获取Bom的视图出错了!");
    //e.printStackTrace();
    }
    return bom; 

    }
    private void make(Bom bom)
    {
    try {
    Statement stmt = conn.createStatement();
    ResultSet rs = stmt.executeQuery("select bom_no,prod_name,prod_no from bs_bom where parent_prod_no ='"+bom.getBom_no()+"'");
    while(rs.next())
    {
    Bom tbom = new Bom();
    tbom.setBom_no(rs.getString(1));
    tbom.setProd_name(rs.getString(2));
    tbom.setProd_no(rs.getString(3));
    tbom.setParent(bom);
    bom.getChilds().add(tbom);
    }
    if(bom.getChilds().size()>0)
    {
    Iterator it = bom.getChilds().iterator();
    while(it.hasNext())
    {
    Bom temp = (Bom)it.next();
    make(temp);
    }
    }
    } catch (SQLException e) {
    // TODO Auto-generated catch block
    Logger.writeLog("获取Bom的视图出错了!");
    //e.printStackTrace();
    }
    }

    public void close()
    {
    try {
    if(conn!=null || !conn.isClosed())
    {
    conn.close();
    conn=null;
    }
    } catch (SQLException e) {
    // TODO Auto-generated catch block
    Logger.writeLog("获取Bom的视图后关闭连接出错!");
    //e.printStackTrace();
    }
    }
    public Bom getBom() {
    return bom;
    }
    public void setBom(Bom bom) {
    this.bom = bom;
    }
    public void expBom(String bomID)
    {
    Bom bom = this.getAlls(bomID);
    expBom(bom);
    }
    private void expBom(Bom bom){
    if(conn==null)
    {
    if(db==null)
    {
    db = new DBConnection();
    }
    if(db!=null)
    {
    conn = db.makeConnection();
    }
    }else
    {
    try {
    String sql="";
    PreparedStatement pstmt1 = conn.prepareStatement("select bomext_no from bs_bomext where bom_no=?");
    pstmt1.setString(1, bom.getBom_no());
    if(pstmt1.executeQuery().next())
    {
    sql = " update bs_bomext set top_prod_no=?,level_no=? ,prod_no=t.prod_no,prod_name=t.prod_name" +
    ",prod_model=t.prod_model,prod_unit=t.prod_unit,use_qty=t.use_qty,re=t.re from bs_bomext d," +
    "(select bom_no,prod_no,prod_name,prod_model,prod_unit,use_qty,re from bs_bom ) t where t.bom_no= ? and d.bom_no=t.bom_no";
    }else
    {
    sql="insert bs_bomext ( " +
    "top_prod_no,level_no,prod_no,prod_name,prod_model,prod_unit,use_qty,re,bom_no )" +
    " select ?,?,prod_no,prod_name,prod_model,prod_unit,use_qty,re,bom_no" +
    " from bs_bom where bom_no=?";
    }
    pstmt1 = conn.prepareStatement(sql);
    pstmt1.setString(1,bom.getTopProdNo());
    pstmt1.setString(2, bom.getLevel()+"");
    pstmt1.setString(3, bom.getBom_no());
    pstmt1.executeUpdate();
    pstmt1.close();
    if(bom.getChilds().size()>0)
    {
    Iterator it = bom.getChilds().iterator();
    while(it.hasNext())
    {
    expBom((Bom)it.next());
    }
    }
    } catch (SQLException e) {
    // TODO Auto-generated catch block
    Logger.writeLog("展开BOM时出错了!\r\n");
    e.printStackTrace();
    }
    }
    }
    /**
     * 根据最高级的Bom编号bomNo,把其下所有的Bom的编号放到List中
     * @param bomNo
     * @param list
     */
    public List getAllBomId(String bomNo)
    {
    Bom bom = getAlls(bomNo);
    List list = new ArrayList();
    getBomNo(bom,list);
    return list;
    }
    private void getBomNo(Bom bom,List list)
    {
    list.add(bom.getBom_no());
    if(bom.getChilds().size()>0)
    {
    Iterator it = bom.getChilds().iterator();
    while(it.hasNext())
    {
    getBomNo((Bom)it.next(),list);
    }
    }
    }}
      

  4.   

    web页面,生成目录结果的那种代码,网上面有很多现成的,搜一下,会用就行了。
    以前用过xloadtree,现在已经不知道怎么用了,呵呵。
      

  5.   

    一般情况下,我会在这个树形结构中加入一个tree_code字读.如root 有001,002,003等而二级目录就是001001,001002表示"欢迎大家参与评论"下的huihzh和test.
    这样是方便查询一个分支上的所有节点.如要查"欢迎大家参与评论"的所有子目录.就可以通过这个tree_code 来查询了.select * from Tabel where tree_code like '001%'.
    你大概明白我上面说的意思了吧?
    至于生成这样的一个树还算比较简单.
    1.先定义一个结构对象.
    SimpleTree类中比如有id,pid(就是你的super_id),treeCode,name,List<SimpleTree> subTree.2.如果你能保证你取出的数据每条记录中PID在读取它之前一定出现过了话,那么就顺序的添加就Ok了.
    就是把当前的对象添加到父对象的subTree中.最终形成的就是对象树结构了.3.如果你不能保证上面的情况的话,那么每次添加一个对象的时候都需要遍历整个对象数,找到相应的父节点,
    然后再添加进去即可.
      

  6.   

    现在关键是不知道怎么快速的去需找一个节点的父节点,难道没增加一个节点就要变了整个树去寻找它的父节点吗?以后这棵树会很大。
    要在web页面中展示这棵树。不知道怎么更快的将无序的数据放到这棵有序的树中。
      

  7.   

    把数据库查询的每一条记录,封装成一个对象。
    然后,创建一个HashMap,key里面保存该对象的ID,value保存该对象的引用。
    这样,你如果想要快速找到父节点,那,可以先找到父节点的ID,
    然后,到HashMap里面get一下,就搞定了。当然,复杂一点,可以建立一个双向的多叉树,来存储这种数据。
    如果嫌访问节点缓慢,可以建立一个HashMap作为索引,就OK了