类似于地区树形结构的构造
程序员文章站
2022-06-30 23:02:57
...
在做项目中经常会用到地区的树形结构,而在数据库中我们一般存储的是一个地区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; // 是*父节点 } } }
推荐阅读
-
vue.js与element-ui实现菜单树形结构的解决方法
-
php实现的树形结构数据存取类实例
-
ReactJs实现树形结构的数据显示的组件的示例
-
javascript如何用递归写一个简单的树形结构示例
-
canvas绘制树形结构可视图形的实现
-
vue实现的树形结构加多选框示例
-
sqlserver实现树形结构递归查询(无限极分类)的方法
-
MabLab中画树状图方法treeplot(nodes)中描述树结构的矢量nodes的构造
-
用JAVA语言实现的凝聚式层次聚类算法 ——基于数据结构中的线性结构和树形结构
-
构造思维+树形结构 Codeforces Round #612 (Div. 2) D题 Numbers on Tree