`

类似于地区树形结构的构造

阅读更多

在做项目中经常会用到地区的树形结构,而在数据库中我们一般存储的是一个地区ID,该地区对应的父节点ID,地区名称。下面仅以安徽省为例展示地区表结构:省 - 市 - 县

areaId  parentId  areaName

136 13 淮南市
135 13 蚌埠市
143 13 阜阳市
139 13 铜陵市
149 13 宣城市
133 13 合肥市
147 13 亳州市
138 13 淮北市
142 13 滁州市

 

。。。。。。

 

856 135 怀远县

857 135 五河县

858 135 固镇县

 

。。。。。。

 

 

需要列出中国每个省下面的市和县。

一种方法是通过表的自连接查询实现,这里不再描述。

第二种方法通过一次sql查询出所有的数据,接着通过递归技术每个省-市,每个省-(市、县)或只有县。

 

    // typeMap 生成t_area表中父节点的所有子孙节点
    Map<Integer, Set<Integer>> typeMap = new HashMap<Integer, Set<Integer>>(); 
    //  typeDirectMap 生成t_area表中父节点的所有直接子节点
    Map<Integer, Set<Integer>> typeDirectMap = new HashMap<Integer, Set<Integer>>(); // parentKey-typeKey
    
       
        List<TArea> areaList = areaService.getArea();
        for (TArea area : areaList) {
            Integer typeKey = area.getTypeKey();
            Integer parentKey = area.getParentKey();
            Set<Integer> set = typeMap.get(parentKey);
            if (null != set) {
                set.add(typeKey);
            } else {
                Set<Integer> newSet = new CopyOnWriteArraySet<Integer>();
                newSet.add(typeKey);
                typeMap.put(parentKey, newSet);
            }
        }
        
        typeDirectMap.putAll(typeMap);
        
        traverseTypeMap(typeMap);
        

 

 

/**
     * 遍历typeMap中所有parent下面的直接child.
     * 
     * @param typeMap
     */
    private static void traverseTypeMap(Map<Integer, Set<Integer>> typeMap) {
        Set<Entry<Integer, Set<Integer>>> set = typeMap.entrySet();
        for (Entry<Integer, Set<Integer>> entry : set) {
            Integer parentKey = entry.getKey();
            Set<Integer> childSet = entry.getValue();
            traverseChild(childSet, parentKey, typeMap);
        }
    }

 

 

/**
     * 遍历childSet
     * 
     * @param childSet
     * @param pk
     * @param typeMap
     */
    private static void traverseChild(Set<Integer> childSet, Integer pk,
            Map<Integer, Set<Integer>> typeMap) {
        for (Integer child : childSet) {
            addAllChildToParent(pk, typeMap, child);
        }
    }

 

 

/**
     * 
     * @param pk 父节点
     * @param typeMap
     * @param ch  子节点
     */
    private static void addAllChildToParent(Integer pk, Map<Integer, Set<Integer>> typeMap, Integer ch) {
        Set<Integer> set = typeMap.get(pk);
        Set<Integer> chSet = typeMap.get(ch);

        if (null != chSet) {
            Set<Integer> parentSet = new HashSet<Integer>();
            addParent(typeMap, pk, parentSet);
            for (Integer p : parentSet) {
                typeMap.get(p).addAll(chSet); // 把当前子节点的集合加入到父节点的所有祖先集合中
            }
            set.addAll(chSet); // 把当前子节点的集合加入到父节点集合中
            traverseChild(chSet, ch, typeMap);
        } else { // 当前子节点集合为空 返回
            return;
        }
    }

 

 

/**
     * 把当前节点pk的所有祖先节点加入到parentSet中.
     * 
     * @param typeMap
     * @param pk
     * @param parentSet
     */
    private static void addParent(Map<Integer, Set<Integer>> typeMap, Integer pk, Set<Integer> parentSet) {
        Set<Entry<Integer, Set<Integer>>> set = typeMap.entrySet();
        for (Entry<Integer, Set<Integer>> entry : set) {
            Integer key = entry.getKey();
            Set<Integer> value = entry.getValue();
            if (value.contains(pk)) {
                parentSet.add(key);
                addParent(typeMap, key, parentSet);
            } else {
                return; // 是顶级父节点
            }
        }
    }

 

 

 

 

 

分享到:
评论

相关推荐

    C++ QT实现类似于Bandizip解压缩的功能

    Qt编写简易的解压缩图形界面,选择文件 ——&gt; 选择压缩文件或解压文件 ——&gt; 开始解压缩并显示进度条 ——&gt; 放到指定文件路径下。采用树形结构存放数据,构造哈夫曼树(即最优编码树),实现解压缩功能。

    java解析xml及4种常用解析比较

    DOM采用建立树形结构的方式访问XML文档,而SAX采用的事件模型。 DOM解析器把XML文档转化为一个包含其内容的树,并可以对树进行遍历。用DOM解析模型的优点是编程容易,开发人员只需要调用建树的指令,然后利用...

    数据结构(C++)有关练习题

    默认构造函数和带数据域、左子树指针、右子树指针的构造函数; b. 按照二叉搜索树的要求设计插入函数Insert(int Info); c. 用递归的方法设计前序遍历和后续遍历函数,遍历时要输出遍历的每个结点; d....

    软件工程知识点

    它使用矩形来表示系统中的子系统或功能模块,使用树形连线结构来表达系统所具有的功能层级关系。 (2)数据流模型。用于描述系统对数据的加工过程,其图形符号是一些具有抽象意义的逻辑符号,主要的图形符号包括:...

    二十三种设计模式【PDF版】

    就是将类用树形结构组合成一个单位.你向别人介绍你是某单位,你是单位中的一个元素,别人和你做买卖,相当于 和单位做买卖。文章中还对 Jive再进行了剖析。 设计模式之 Decorator(装饰器) Decorator 是个油漆工,给...

    数据挖掘技术分析.doc

    3 数据挖掘的主要方法 1) 决策树法 决策树是一种对实例进行分类的树形结构,由节点和有向边组成。节点的类型 有2种:内部节点和叶子节点。内部节点一般表示一个特征或属性的测试条件,叶子节点 则表示一个分类。 ...

    计算机二级公共基础知识

    在树结构中,每一个结点只有一个前件,称为父结点,没有前件的结点只有一个,称为树的根结点,简称树的根。例如,在图1-1中,结点A是树的根结点。 子结点和 叶子结点 在树结构中,每一个结点可以有多个后件,称为该...

    算法导论(part1)

    ·在第12.4节中,对随机构造二叉查找树的高度,给出了一个简单得多的分析。 ·对动态规划元素的讨论(第15.3节)和对贪心算法元素的讨论(第16.2节)大大地扩展了。关于活动选择问题的解释在贪心算法一章中开始出现...

    算法导论(part2)

    ·在第12.4节中,对随机构造二叉查找树的高度,给出了一个简单得多的分析。 ·对动态规划元素的讨论(第15.3节)和对贪心算法元素的讨论(第16.2节)大大地扩展了。关于活动选择问题的解释在贪心算法一章中开始出现...

    JAVA上百实例源码以及开源项目

    1个目标文件,JNDI的使用例子,有源代码,可以下载参考,JNDI的使用,初始化Context,它是连接JNDI树的起始点,查找你要的对象,打印找到的对象,关闭Context…… ftp文件传输 2个目标文件,FTP的目标是:(1)提高...

    JAVA上百实例源码以及开源项目源代码

    1个目标文件,JNDI的使用例子,有源代码,可以下载参考,JNDI的使用,初始化Context,它是连接JNDI树的起始点,查找你要的对象,打印找到的对象,关闭Context…… ftp文件传输 2个目标文件,FTP的目标是:(1)提高...

    java源码包---java 源码 大量 实例

    1个目标文件,JNDI的使用例子,有源代码,可以下载参考,JNDI的使用,初始化Context,它是连接JNDI树的起始点,查找你要的对象,打印找到的对象,关闭Context…… ftp文件传输 2个目标文件,FTP的目标是:(1)提高...

    易语言程序免安装版下载

    修改扩展界面支持库一,为“树形框”增加多态检查框功能,相应地添加了多个与检查框相关的属性、方法和事件。 17. 修改高级表格支持库,允许“复制选定文本()”“剪切选定文本()”在“允许选择块”属性为假时复制...

    java源码包2

    1个目标文件,JNDI的使用例子,有源代码,可以下载参考,JNDI的使用,初始化Context,它是连接JNDI树的起始点,查找你要的对象,打印找到的对象,关闭Context…… ftp文件传输 2个目标文件,FTP的目标是:(1)提高...

    java源码包3

    1个目标文件,JNDI的使用例子,有源代码,可以下载参考,JNDI的使用,初始化Context,它是连接JNDI树的起始点,查找你要的对象,打印找到的对象,关闭Context…… ftp文件传输 2个目标文件,FTP的目标是:(1)提高...

    java源码包4

    1个目标文件,JNDI的使用例子,有源代码,可以下载参考,JNDI的使用,初始化Context,它是连接JNDI树的起始点,查找你要的对象,打印找到的对象,关闭Context…… ftp文件传输 2个目标文件,FTP的目标是:(1)提高...

    成百上千个Java 源码DEMO 4(1-4是独立压缩包)

    EJB中JNDI的使用源码例子 1个目标文件,JNDI的使用例子,有源代码,可以下载参考,JNDI的使用,初始化Context,它是连接JNDI树的起始点,查找你要的对象,打印找到的对象,关闭Context…… ftp文件传输 2个目标文件...

    成百上千个Java 源码DEMO 3(1-4是独立压缩包)

    EJB中JNDI的使用源码例子 1个目标文件,JNDI的使用例子,有源代码,可以下载参考,JNDI的使用,初始化Context,它是连接JNDI树的起始点,查找你要的对象,打印找到的对象,关闭Context…… ftp文件传输 2个目标文件...

Global site tag (gtag.js) - Google Analytics