樹的結構:node
示例中本身構建了圖片中的這棵樹:ide
public class TreeNode { String value; List<TreeNode> children; public TreeNode() { children = new ArrayList<>(); } public TreeNode(String value) { this.value = value; children = new ArrayList<>(); } @Override public String toString() { // TODO Auto-generated method stub return value; } }
// 建立一棵樹 TreeNode root = new TreeNode("A"); // 第二層 root.children.add(new TreeNode("B")); root.children.add(new TreeNode("C")); // 第三層 root.children.get(0).children.add(new TreeNode("D")); root.children.get(0).children.add(new TreeNode("E")); root.children.get(1).children.add(new TreeNode("F")); root.children.get(1).children.add(new TreeNode("H")); root.children.get(1).children.add(new TreeNode("G")); // 第四層 root.children.get(0).children.get(1).children.add(new TreeNode("I"));
提供三種方式進行遍歷:this
/** * 深度優先遍歷(遞歸方式) --- 樹(Tree) */ public void recurTree(TreeNode root) { List<List<String>> result = new ArrayList<>(); List<String> path = new ArrayList<>(); path.add(root.value); findPath(result, root, path); System.out.println(result); } private void findPath(List<List<String>> result, TreeNode node, List<String> path) { if (node.children == null || node.children.size() <= 0) { result.add(path); return; } for (int i = 0; i < node.children.size(); i++) { TreeNode child = node.children.get(i); List<String> cPath = new ArrayList<>(); cPath.addAll(path); cPath.add(child.value); findPath(result, child, cPath, target); } }
/** * 深度優先遍歷(非遞歸方式) ----- 查找樹的全部葉子路徑 * * @param root * 根節點 * @return 葉子路徑的集合 */ public List<List<TreeNode>> dfsTree(TreeNode root) { Stack<TreeNode> nodeStack = new Stack<>(); Stack<List<TreeNode>> pathStack = new Stack<>(); List<List<TreeNode>> result = new ArrayList<>(); nodeStack.push(root); ArrayList<TreeNode> arrayList = new ArrayList<>(); arrayList.add(root); pathStack.push(arrayList); while (!nodeStack.isEmpty()) { TreeNode curNode = nodeStack.pop(); List<TreeNode> curPath = pathStack.pop(); if (curNode.children == null || curNode.children.size() <= 0) { result.add(curPath); } else { int childSize = curNode.children.size(); for (int i = childSize - 1; i >= 0; i--) { TreeNode node = curNode.children.get(i); nodeStack.push(node); List<TreeNode> list = new ArrayList<>(curPath); list.add(node); pathStack.push(list); } } } return result; }
/** * 廣度優先遍歷 ---- 查找樹的全部葉子路徑 * * @param root * 根節點 * @return 葉子路徑的集合 */ public List<List<TreeNode>> bfsTree(TreeNode root) { Queue<TreeNode> nodeQueue = new LinkedList<>(); Queue<List<TreeNode>> qstr = new LinkedList<>(); List<List<TreeNode>> result = new ArrayList<>(); nodeQueue.add(root); ArrayList<TreeNode> arrayList = new ArrayList<>(); qstr.add(arrayList); while (!nodeQueue.isEmpty()) { TreeNode curNode = nodeQueue.remove(); List<TreeNode> curList = qstr.remove(); if (curNode.children == null || curNode.children.size() <= 0) { curList.add(curNode); result.add(curList); } else { for (int i = 0; i < curNode.children.size(); i++) { TreeNode treeNode = curNode.children.get(i); nodeQueue.add(treeNode); List<TreeNode> list = new ArrayList<>(curList); list.add(curNode); qstr.add(list); } } } return result; }
深度優先遍歷(遞歸):[[A, B, D], [A, B, E, I], [A, C, F], [A, C, H], [A, C, G]]
廣度優先遍歷:[[A, B, D], [A, C, F], [A, C, H], [A, C, G], [A, B, E, I]]
深度優先遍歷(非遞歸):[[A, B, D], [A, B, E, I], [A, C, F], [A, C, H], [A, C, G]]
示例是查找樹的全部葉子節點,觸類旁通,若是咱們是查找樹中知足某個條件的路徑,也是很是容易了。好比下面中查找 「 E 」 的分支:spa
public void recurTree(TreeNode root) { List<List<String>> result = new ArrayList<>(); List<String> path = new ArrayList<>(); path.add(root.value); findPath(result, root, path, "E"); System.out.println(result); } private void findPath(List<List<String>> result, TreeNode node, List<String> path, String target) { if (target.equals(node.value)) { result.add(path); return; } if (node.children == null || node.children.size() <= 0) { return; } for (int i = 0; i < node.children.size(); i++) { TreeNode child = node.children.get(i); List<String> cPath = new ArrayList<>(); cPath.addAll(path); cPath.add(child.value); if (result.size() > 0) break; findPath(result, child, cPath, target); } }
[[A, B, E]]