递归
python实现代码
def recursion(level, param1, param2, ...):
#递归出口
if level > MAX_LEVEL:
process_result
return
#处理当前层逻辑
process(level, data...)
#下探到下一层
self.recursion(level + 1, p1, ...)
#清理当前层
java代码实现
public void recursion(int level, int param1, int param2, ...) {
//递归出口
if (level > MAX_LEVEL) {
processResult();
return;
}
//处理当前层逻辑
process(level, data);
//下探到下一层
recursion(level + 1, p1, ...);
//清理当前层
}
go代码实现
func recursion(level int, param1 int, param2 int, ...) {
//递归出口
if level > MAX_LEVEL {
processResult()
return
}
//处理当前层逻辑
process(level, data)
//下探到下一层
recursion(level + 1, p1, ...)
//清理当前层
}
分治
python实现代码
def divide_conquer(problem, param1, param2, ...):
#递归出口
if problem is None:
print_result
return
#准备数据
data = prepare_data(problem)
subproblems = split_problem(problem, data)
#拆分为子问题
#调子问题的递归函数
subresult1 = self.divide_conquer(subproblem[0], p1, ...)
subresult2 = self.divide_conquer(subproblem[1], p1, ...)
subresult3 = self.divide_conquer(subproblem[2], p1, ...)
...
#处理并生成最终结果
result = process_result(subresult1, subresult2, subresult3, ...)
#恢复当前级别状态
java代码实现
public class DivideConquer {
public void divideConquer(Problem problem, int param1, int param2, ...) {
// 递归出口
if (problem == null) {
printResult();
return;
}
// 准备数据
Data data = prepareData(problem);
List<SubProblem> subproblems = splitProblem(problem, data);
// 拆分为子问题,调用子问题的递归函数
Result subresult1 = divideConquer(subproblems.get(0), p1, ...);
Result subresult2 = divideConquer(subproblems.get(1), p1, ...);
Result subresult3 = divideConquer(subproblems.get(2), p1, ...);
// ...
// 处理并生成最终结果
Result result = processResult(subresult1, subresult2, subresult3, ...);
// 恢复当前级别状态
}
go代码实现
func divideConquer(problem Problem, param1 int, param2 int, ...) Result {
// 递归出口
if problem == nil {
printResult()
return Result{}
}
// 准备数据
data := prepareData(problem)
subproblems := splitProblem(problem, data)
// 拆分为子问题,调用子问题的递归函数
subresult1 := divideConquer(subproblems[0], p1, ...)
subresult2 := divideConquer(subproblems[1], p1, ...)
subresult3 := divideConquer(subproblems[2], p1, ...)
// ...
// 处理并生成最终结果
result := processResult(subresult1, subresult2, subresult3, ...)
// 恢复当前级别状态
return result
}
DFS
python实现代码
visited = set()
def dfs(node, visited):
visited.add(node)
#在此处处理当前节点
...
for next_node in node.children():
if not next_node in visited:
dfs(next node, visited)
java代码实现
public class Solution {
public Set<Integer> visited = new HashSet<>();
public void dfs(Node node, Set<Integer> visited) {
visited.add(node.val);
// 在此处处理当前节点
// ...
for (Node nextNode : node.children()) {
if (!visited.contains(nextNode.val)) {
dfs(nextNode, visited);
}
}
}
}
go代码实现
var visited = make(map[int]bool)
type Node struct {
val int
children []*Node
}
func dfs(node *Node, visited map[int]bool) {
visited[node.val] = true
// 在此处处理当前节点
// ...
for _, nextNode := range node.children {
if !visited[nextNode.val] {
dfs(nextNode, visited)
}
}
}
其中visited集合:用于记录已经访问过的节点,防止重复访问
遍历相邻节点:通过node.children()方法获取当前节点的相邻节点,遍历相邻节点进行递归调用
其中非递归写法
python代码实现
def DFS(self, tree):
if tree.root is None:
return []
visited, stack = [], [tree.root]
while stack:
node = stack.pop()
visited.add(node)
process(node)
nodes = generate_related_nodes(node)
stack.push(nodes)
#其他处理工作
java代码实现
public class DFS {
public void DFS(Tree tree) {
if (tree.getRoot() == null) {
return;
}
HashSet<Node> visited = new HashSet<>();
Stack<Node> stack = new Stack<>();
stack.push(tree.getRoot());
while (!stack.isEmpty()) {
Node node = stack.pop();
visited.add(node);
process(node);
List<Node> nodes = generateRelatedNodes(node);
for (Node n : nodes) {
stack.push(n);
}
}
// 其他处理工作
}
go代码实现
func DFS(tree Tree) {
if tree.Root == nil {
return
}
visited := make(map[*Node]bool)
stack := []*Node{tree.Root}
for len(stack) > 0 {
node := stack[len(stack)-1]
stack = stack[:len(stack)-1]
visited[node] = true
process(node)
nodes := generateRelatedNodes(node)
for _, n := range nodes {
stack = append(stack, n)
}
}
// 其他处理工作
}
这种非递归实现DFS(深度优先搜索)的方法使用了一个栈(Stack)来辅助遍历图或树结构。下面是这种非递归实现DFS的工作原理:
- 首先,将根节点压入栈中,并创建一个集合用于记录已访问的节点。
- 在循环中,不断从栈中弹出一个节点,并将其标记为已访问。
- 对当前节点进行处理(如输出、记录等)。
- 生成当前节点的相邻节点(或子节点),并将这些相邻节点压入栈中。
- 重复步骤2到步骤4,直到栈为空。
- 在循环外部,可以进行其他处理工作
BFS
python实现代码
def BFS(graph, start, end):
#用于存储待访问的节点,起到广度优先搜索的作用
queue = []
#将起始节点作为列表添加到队列中,表示从起始节点开始进行搜索
queue.append([start])
#将起始节点标记为已访问
visited.add(start)
#当队列不为空时,持续进行广度优先搜索
while queue:
node = queue.pop()
visited.add(node)
process(node)
#根据当前节点生成与之相邻的节点
nodes = generate_related_nodes(node)
#将生成的相邻节点添加到队列中,准备下一轮的广度优先搜索
queue.push(nodes)
#其他处理工作
...
java代码实现
public class BFS {
public void bfs(Map<Integer, List<Integer>> graph, int start, int end) {
Queue<Integer> queue = new LinkedList<>();
Set<Integer> visited = new HashSet<>();
queue.add(start);
visited.add(start);
while (!queue.isEmpty()) {
int node = queue.poll();
visited.add(node);
process(node);
List<Integer> nodes = graph.get(node);
for (int nextNode : nodes) {
if (!visited.contains(nextNode)) {
queue.add(nextNode);
}
}
}
// 其他处理工作
}
go代码实现
func bfs(graph map[int][]int, start int, end int) {
queue := []int{start}
visited := make(map[int]bool)
visited[start] = true
for len(queue) > 0 {
node := queue[0]
queue = queue[1:]
visited[node] = true
process(node)
nodes := graph[node]
for _, nextNode := range nodes {
if !visited[nextNode] {
queue = append(queue, nextNode)
}
}
}
// 其他处理工作
}