Java多叉樹遞迴演算法構造樹形結構JSON
阿新 • • 發佈:2022-03-20
構造如下JSON結構:
{ id: '100000', text: '廊坊銀行總行', children: [ { id: '110000', text: '廊坊分行', children: [ { id: '113000', text: '廊坊銀行開發區支行', leaf: true }, { id: '112000', text: '廊坊銀行解放道支行', children: [ { id: '112200', text: '廊坊銀行三大街支行', leaf: true }, { id: '112100', text: '廊坊銀行廣陽道支行', leaf: true } ] }, { id: '111000', text: '廊坊銀行金光道支行', leaf: true } ] } ] }
實現這樣一顆樹,需要設計兩個類:樹類(MultiwayTree)、節點類(Node);排序時還需要一個比較器類(NodeIDComparator);為了方便演示,還需要構造一些假的層次資料,因此還需要建一個構造假資料的類(VirtualDataGenerator),以下程式碼拷貝出來之後可直接執行測試:
package test; import java.util.ArrayList; import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Collections; /** * 多叉樹類 */ public class MultiwayTree { public static void main(String[] args) { // 讀取層次資料結果集列表 List dataList = VirtualDataGenerator.getVirtualResult(); // 節點對映表,用於臨時儲存節點物件 HashMap nodeMap = new HashMap(); // 根節點 Node root = null; // 將結果集存入對映表(後面將藉助對映表構造多叉樹) for (Iterator it = dataList.iterator(); it.hasNext();) { Map dataRecord = (Map) it.next(); Node node = new Node(); node.id = (String) dataRecord.get("id"); node.text = (String) dataRecord.get("text"); node.parentId = (String) dataRecord.get("parentId"); nodeMap.put(node.id, node); } // 構造無序的多叉樹 Set entrySet = nodeMap.entrySet(); for (Iterator it = entrySet.iterator(); it.hasNext();) { Node node = (Node) ((Map.Entry) it.next()).getValue(); if (node.parentId == null || node.parentId.equals("")) { root = node; } else { ((Node) nodeMap.get(node.parentId)).addChild(node); } } // 輸出無序的樹形結構的JSON字串 System.out.println(root); // 對多叉樹進行橫向排序 root.sortChildren(); // 輸出有序的樹形結構的JSON字串 System.out.println(root); // 程式輸出結果如下: // // 無序的樹形結構(格式化後的結果,可使用JSON格式化工具檢視,例如 http://jsonviewer.stack.hu/ 線上檢視器): // { // id : '100000', // text : '廊坊銀行總行', // children : [ // { // id : '110000', // text : '廊坊分行', // children : [ // { // id : '113000', // text : '廊坊銀行開發區支行', // leaf : true // }, // { // id : '111000', // text : '廊坊銀行金光道支行', // leaf : true // }, // { // id : '112000', // text : '廊坊銀行解放道支行', // children : [ // { // id : '112200', // text : '廊坊銀行三大街支行', // leaf : true // }, // { // id : '112100', // text : '廊坊銀行廣陽道支行', // leaf : true // } // ] // } // ] // } // ] // } // 有序的樹形結構(格式化後的結果): // { // id : '100000', // text : '廊坊銀行總行', // children : [ // { // id : '110000', // text : '廊坊分行', // children : [ // { // id : '111000', // text : '廊坊銀行金光道支行', // leaf : true // }, // { // id : '112000', // text : '廊坊銀行解放道支行', // children : [ // { // id : '112100', // text : '廊坊銀行廣陽道支行', // leaf : true // }, // { // id : '112200', // text : '廊坊銀行三大街支行', // leaf : true // } // ] // }, // { // id : '113000', // text : '廊坊銀行開發區支行', // leaf : true // } // ] // } // ] // } } } /** * 節點類 */ class Node { /** * 節點編號 */ public String id; /** * 節點內容 */ public String text; /** * 父節點編號 */ public String parentId; /** * 孩子節點列表 */ private List children = new ArrayList(); // 新增孩子節點 public void addChild(Node node) { children.add(node); } // 先序遍歷,拼接JSON字串 public String toString() { String result = "{" + "id : '" + id + "'" + ", text : '" + text + "'"; if (children.size() != 0) { result += ", children : ["; for (int i = 0; i < children.size(); i++) { result += ((Node) children.get(i)).toString() + ","; } result = result.substring(0, result.length() - 1); result += "]"; } else { result += ", leaf : true"; } return result + "}"; } // 兄弟節點橫向排序 public void sortChildren() { if (children.size() != 0) { // 對本層節點進行排序(可根據不同的排序屬性,傳入不同的比較器,這裡 傳入ID比較器) Collections.sort(children, new NodeIDComparator()); // 對每個節點的下一層節點進行排序 for (int i = 0; i < children.size(); i++) { ((Node) children.get(i)).sortChildren(); } } } } /** * 節點比較器 */ class NodeIDComparator implements Comparator { // 按照節點編號比較 public int compare(Object o1, Object o2) { int j1 = Integer.parseInt(((Node) o1).id); int j2 = Integer.parseInt(((Node) o2).id); return (j1 < j2 ? -1 : (j1 == j2 ? 0 : 1)); } } /** * 構造虛擬的層次資料 */ class VirtualDataGenerator { // 構造無序的結果集列表,實際應用中,該資料應該從資料庫中查詢獲得; public static List getVirtualResult() { List dataList = new ArrayList(); HashMap dataRecord1 = new HashMap(); dataRecord1.put("id", "112000"); dataRecord1.put("text", "廊坊銀行解放道支行"); dataRecord1.put("parentId", "110000"); HashMap dataRecord2 = new HashMap(); dataRecord2.put("id", "112200"); dataRecord2.put("text", "廊坊銀行三大街支行"); dataRecord2.put("parentId", "112000"); HashMap dataRecord3 = new HashMap(); dataRecord3.put("id", "112100"); dataRecord3.put("text", "廊坊銀行廣陽道支行"); dataRecord3.put("parentId", "112000"); HashMap dataRecord4 = new HashMap(); dataRecord4.put("id", "113000"); dataRecord4.put("text", "廊坊銀行開發區支行"); dataRecord4.put("parentId", "110000"); HashMap dataRecord5 = new HashMap(); dataRecord5.put("id", "100000"); dataRecord5.put("text", "廊坊銀行總行"); dataRecord5.put("parentId", ""); HashMap dataRecord6 = new HashMap(); dataRecord6.put("id", "110000"); dataRecord6.put("text", "廊坊分行"); dataRecord6.put("parentId", "100000"); HashMap dataRecord7 = new HashMap(); dataRecord7.put("id", "111000"); dataRecord7.put("text", "廊坊銀行金光道支行"); dataRecord7.put("parentId", "110000"); dataList.add(dataRecord1); dataList.add(dataRecord2); dataList.add(dataRecord3); dataList.add(dataRecord4); dataList.add(dataRecord5); dataList.add(dataRecord6); dataList.add(dataRecord7); return dataList; } }