二叉樹DFS和BFS 遞迴/非遞迴
阿新 • • 發佈:2018-12-04
二叉樹DFS和BFS 遞迴/非遞迴方式
1.DFS
DFS, 深度優先遍歷
(1)遞迴形式
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
List<TreeNode> list = new ArrayList<>(); public List<TreeNode> traversal(TreeNode root) { dfs(root); return list; } private void dfs(TreeNode root) { if (root == null) return; list.add(root); dfs(root.left); dfs(root.right); }
(2)非遞迴形式 (利用棧來遞迴)
public List<TreeNode> traversal(TreeNode root) { if (root == null) return null; List<TreeNode> res = new ArrayList<>(); Stack<TreeNode> stack = new Stack<>(); stack.add(root); while(!stack.empty()) { TreeNode node = stack.pop(); res.add(node); if (node.right != null) { stack.push(node.right); } if (node.left != null) { stack.push(node.left); } } return res; }
2.BFS
BFS,廣度優先遍歷,對應二叉樹的層級遍歷
(1)非遞迴形式 (利用佇列實現遍歷)
public List<TreeNode> traversal(TreeNode root) { if (root == null) return null; return bfs(root); } private List<TreeNode> bfs(TreeNode root) { //if (root == null) return null; int curNum = 1; //維護當前層的node數量 int nextNum = 0; //維護下一層的node數量 Queue<TreeNode> queue = new LinkedList<>(); List<TreeNode> list = new ArrayList<>(); queue.offer(root); while(!queue.isEmpty()) { TreeNode node = queue.poll(); list.add(node); curNum--; if (node.left != null) { queue.add(node.left); nextNum++; } if (node.right != null) { queue.add(node.right); nextNum++; } if (curNum == 0) { curNum = nextNum; nextNum = 0; } } return list; }
(2)遞迴形式
這裡所謂的bfs遞迴形式,是利用dfs的遞迴形式,在遞迴過程中記錄每個node的level,然後將屬於一個level的node放到一list裡面
public List<List<TreeNode>> traversal(TreeNode root) {
if (root == null) return null;
List<List<TreeNode>> list = new ArrayList<>();
dfs(root, 0, list);
return list;
}
private void dfs(TreeNode root, int level, List<List<TreeNode>> list) {
if (root == null) return;
if (level >= list.size()) {
List<TreeNode> subList = new ArrayList<>();
subList.add(root);
list.add(subList);
} else {
list.get(level).add(root);
}
dfs(root.left, level+1, list);
dfs(root.right, level+1, list);
}
圖的深度優先遍歷和廣度優先遍歷,和二叉樹的dfs、bfs原理的相同的。一般,深度優先遍歷利用棧來實現(或者遞迴),廣度優先遍歷利用佇列來實現。