Java多叉樹的生成初始化和遍歷以及查找


/**
 * 〈一句話功能簡述〉<br> 
 * 〈屬性〉
 *
 * @author zhoumoxuan
 * @create 8/22/18
 * @since 1.0.0
 */
public class Test {
    private int id;
    private int pid;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getPid() {
        return pid;
    }

    public void setPid(int pid) {
        this.pid = pid;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}


import java.util.List;
import java.util.ArrayList;
import java.io.Serializable;

/**
 * 〈一句話功能簡述〉<br>
 * 〈樹形結構〉
 *
 * @author zhoukai7
 * @create 8/22/18
 * @since 1.0.0
 */
public class TreeNode implements Serializable {
    private int parentId;//父親ID
    private int ownId;//孩子ID
    protected String nodeName;//節點名稱
    protected TreeNode parentNode;
    protected List<TreeNode> childList;

    /**
     * 必須進程初始化否則會拋出異常
     */
    public TreeNode() {
        initChildList();
    }

    public TreeNode(TreeNode parentNode) {
        this.getParentNode();
        initChildList();
    }

    public boolean isLeaf() {
        if (childList == null) {
            return true;
        } else {
            if (childList.isEmpty()) {
                return true;
            } else {
                return false;
            }
        }
    }

    /**
     * 插入一個child節點到當前節點
     *
     * @param treeNode
     */
    public void addChildNode(TreeNode treeNode) {
        initChildList();
        childList.add(treeNode);
    }

    public void initChildList() {
        if (childList == null) {
            childList = new ArrayList<TreeNode>();
        }

    }

    /**
     * 判斷是否是有效的節點
     *
     * @return
     */
    public boolean isValidTree() {
        return true;
    }

    /**
     * 返回當前節點的父輩級別的節點列表
     *
     * @return
     */
    public List<TreeNode> getElders() {
        List<TreeNode> elderList = new ArrayList<TreeNode>();
        TreeNode parentNode = this.getParentNode();
        if (parentNode == null) {
            return elderList;
        } else {
            elderList.add(parentNode);
            elderList.addAll(parentNode.getElders());
            return elderList;
        }
    }

    /**
     * 返回當前節點的子孫輩的列表
     *
     * @return
     */
    public List<TreeNode> getJuniors() {
        List<TreeNode> juniorList = new ArrayList<TreeNode>();
        List<TreeNode> childList = this.getChildList();
        if (childList == null) {
            return juniorList;
        } else {
            int childNumber = childList.size();
            for (int i = 0; i < childNumber; i++) {
                TreeNode junior = childList.get(i);
                juniorList.add(junior);
                juniorList.addAll(junior.getJuniors());
            }
            return juniorList;
        }
    }

    /**
     * 返回當前節點的所有的孩子
     *
     * @return
     */
    public List<TreeNode> getChildList() {
        return childList;
    }

    /**
     * 刪除當前節點和它的子孫
     */
    public void deleteNode() {
        TreeNode parentNode = this.getParentNode();
        int id = this.getOwnId();

        if (parentNode != null) {
            parentNode.deleteChildNode(id);
        }
    }

    /**
     * 刪除當前節點的某個孩子節點
     *
     * @param childId
     */
    public void deleteChildNode(int childId) {
        List<TreeNode> childList = this.getChildList();
        int childNumber = childList.size();
        for (int i = 0; i < childNumber; i++) {
            TreeNode child = childList.get(i);
            if (child.getOwnId() == childId) {
                childList.remove(i);
                return;
            }
        }
    }

    /**
     * 當前節點中插入新節點
     *
     * @param treeNode
     * @return
     */
    public boolean insertNewNode(TreeNode treeNode) {
        int newParentId = treeNode.getParentId();
        //如果相等則新增加list保存該節點
        if (this.parentId == newParentId) {
            addChildNode(treeNode);
            return true;
        } else {
            List<TreeNode> childList = this.getChildList();
            int size = childList.size();
            boolean flag;
            //如果不存在則需要從該節點的子節點列表循環查找
            for (int i = 0; i < size; i++) {
                TreeNode childNode = childList.get(i);
                flag = childNode.insertNewNode(treeNode);
                if (flag == true) {
                    return true;
                }

            }
            return false;
        }
    }

    /**
     * 查找樹中某個節點
     *
     * @param id
     * @return
     */
    public TreeNode findTreeNodeById(int id) {
        if (this.ownId == id) {
            return this;
        }

        if (childList.isEmpty() || childList == null) {
            return null;
        } else {
            int size = childList.size();
            for (int i = 0; i < size; i++) {
                TreeNode child = childList.get(i);
                TreeNode result = child.findTreeNodeById(id);
                if (result != null) {
                    return result;
                }
            }
            return null;
        }
    }

    /**
     * 遍歷樹
     */
    public void traverseTree() {
        if (ownId < 0) {
            return;
        }
        if (childList == null || childList.isEmpty()) {
            return;
        }

        int size = childList.size();
        for (int i = 0; i < size; i++) {
            TreeNode child = childList.get(i);
            child.traverseTree();
        }
    }


    /**
     * 遍歷樹同時保存該節點中的parentNode屬性
     *
     * @param treeNode
     */
    public void traverseTreeAndSaveParentNode(TreeNode treeNode) {
        if (ownId < 0) {
            return;
        }
        if (childList == null || childList.isEmpty()) {
            return;
        }

        int size = childList.size();
        for (int i = 0; i < size; i++) {
            TreeNode child = childList.get(i);
            //treeNode.getChildList().clear();//此處可以清除數據如果嫌冗餘
            child.setParentNode(treeNode);
            child.traverseTreeAndSaveParentNode(child);
        }
    }


    public void setChildList(List<TreeNode> childList) {
        this.childList = childList;
    }

    public int getParentId() {
        return parentId;
    }

    public void setParentId(int parentId) {
        this.parentId = parentId;
    }

    public int getOwnId() {
        return ownId;
    }

    public void setOwnId(int ownId) {
        this.ownId = ownId;
    }

    public TreeNode getParentNode() {
        return parentNode;
    }

    public void setParentNode(TreeNode parentNode) {
        this.parentNode = parentNode;
    }

    public String getNodeName() {
        return nodeName;
    }

    public void setNodeName(String nodeName) {
        this.nodeName = nodeName;
    }

}

/**
 * 〈一句話功能簡述〉<br> 
 * 〈樹形工具類〉
 *
 * @author zhoukai7
 * @create 8/22/18
 * @since 1.0.0
 */
import java.util.List;
import java.util.Iterator;
import java.util.HashMap;

public class TreeNodeUtil {
    private TreeNode root;
    private List<TreeNode> nodeList;
    private boolean isValidTree = true;

    public TreeNodeUtil() {
    }

    public TreeNodeUtil(List<TreeNode> treeNodeList) {
        nodeList = treeNodeList;
        createTree();
    }

    public static TreeNode getTreeNodeById(TreeNode tree, int id) {
        if (tree == null) {
            return null;
        }

        TreeNode treeNode = tree.findTreeNodeById(id);
        return treeNode;
    }

    /**
     * 從給定的treeNode或實體列表中生成一個樹
     */
    public void createTree() {
        HashMap nodeMap = traverseNodeToMap();
        relevancyNodeToMap(nodeMap);
    }

    /**
     * 便利list保存node節點到Map中
     */
    protected HashMap traverseNodeToMap() {
        int maxId = Integer.MAX_VALUE;
        HashMap nodeMap = new HashMap<String, TreeNode>();
        Iterator it = nodeList.iterator();
        while (it.hasNext()) {
            TreeNode treeNode = (TreeNode) it.next();
            int id = treeNode.getOwnId();
            if (id < maxId) {
                maxId = id;
                this.root = treeNode;
            }
            String keyId = String.valueOf(id);

            nodeMap.put(keyId, treeNode);
        }
        return nodeMap;
    }

    /**
     * 把list中的TreeNode進行父親孩子節點互相關聯
     */
    protected void relevancyNodeToMap(HashMap nodeMap) {
        Iterator it = nodeMap.values().iterator();
        while (it.hasNext()) {
            TreeNode treeNode = (TreeNode) it.next();
            int parentId = treeNode.getParentId();
            String parentKeyId = String.valueOf(parentId);
            if (nodeMap.containsKey(parentKeyId)) {
                TreeNode parentNode = (TreeNode) nodeMap.get(parentKeyId);
                if (parentNode == null) {
                    this.isValidTree = false;
                    return;
                } else {
                    //這裏需要把父親節點做關聯用於查找使用
                    parentNode.addChildNode(treeNode);
                }
            }
        }
    }


    /**
     * 判斷是否有效的樹
     */
    public boolean isValidTree() {
        return this.isValidTree;
    }

    public TreeNode getRoot() {
        return root;
    }

    public void setRoot(TreeNode root) {
        this.root = root;
    }

    public List<TreeNode> getNodeList() {
        return nodeList;
    }

    public void setNodeList(List<TreeNode> nodeList) {
        this.nodeList = nodeList;
    }
}



import java.util.ArrayList;
import java.util.List;

/**
 * 〈一句話功能簡述〉<br> 
 * 〈測試類〉
 *
 * @author zhoumoxuan
 * @create 8/22/18
 * @since 1.0.0
 */
public class TestTree {

    public static void main(String[] args){
        //獲取業務list數據
        List<Test> listAll = null;
        //new一個list保存全部節點
        List<TreeNode> listNode = new ArrayList<TreeNode>();
        //2、必須初始化一個root節點,保證根的唯一性
        TreeNode treeNode2 = new TreeNode();
        treeNode2.setParentId(0);
        treeNode2.setOwnId(0);
        treeNode2.setNodeName("root");
        listNode.add(treeNode2);

        //3、循環遍歷所有
        for (int j = 0; j < listAll.size(); j++) {

            Test sysDeptEntity = listAll.get(j);
            TreeNode treeNode = new TreeNode();
            treeNode.setParentId(sysDeptEntity.getPid());
            treeNode.setOwnId(sysDeptEntity.getId());
            treeNode.setNodeName(sysDeptEntity.getName());
            listNode.add(treeNode);
        }

        //4、綁定父節點跟子節點的關係
        TreeNodeUtil treeHelper = new TreeNodeUtil(listNode);
        TreeNode treeNode = treeHelper.getRoot();
        // 這裏默認生成了一次多餘的root子節點,必須執行刪除
        treeNode.deleteChildNode(0);
        treeNode.traverseTreeAndSaveParentNode(treeNode);
        //獲取樹形
        TreeNode treeNode4 = treeHelper.getRoot();

    }

}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章