如何在Java中将这种广度优先搜索转换为静态方法?

我在Python中编写了这个静态方法,以进行广度优先搜索。但是,我主要使用Java,并且我想了解数据结构如何转换为Java,给定的泛型等。我的代码是:


def bfs(graph, start_vertex, target_value):

  path = [start_vertex] #a list that contains start_vertex

  vertex_and_path = [start_vertex, path] #a list that contains start_vertex and path

  bfs_queue = [vertex_and_path]

  visited = set() #visited defined as an empty set


  while bfs_queue: #while the queue is not empty

    current_vertex, path = bfs_queue.pop(0) #removes element from queue and sets both equal to that first element

    visited.add(current_vertex) #adds current vertex to visited list


    for neighbor in graph[current_vertex]: #looks at all neighboring vertices

      if neighbor not in visited: #if neighbor is not in visited list

        if neighbor is target_value: #if it's the target value

          return path + [neighbor] #returns path with neighbor appended

        else:

          bfs_queue.append([neighbor, path + [neighbor]]) #recursive call with path that has neighbor appended

我会用这个图表是:


myGraph = { //I'm not sure how to structure this in Java

    'lava': set(['sharks', 'piranhas']),

    'sharks': set(['lava', 'bees', 'lasers']),

    'piranhas': set(['lava', 'crocodiles']),

    'bees': set(['sharks']),

    'lasers': set(['sharks', 'crocodiles']),

    'crocodiles': set(['piranhas', 'lasers'])

  }

我会称之为


public static void main(String[] args){

    System.out.println(bfs(myGraph, "crocodiles", "bees"));

}

到目前为止,这是我拥有的Java:


    public class BreadthFirstSearch{


    ///NOT DONE YET

    public static ArrayList<String> BFS(Map<String, String[]> graph, String start, String target) {

            List<String> path = new ArrayList<>();

            }

        }

}


Helenr
浏览 80回答 2
2回答

一只斗牛犬

翻译上做得很好。让我提供我的代码,然后解释一下:import java.util.*;class BreadthFirstSearch {&nbsp; &nbsp; public static ArrayList<String> BFS(&nbsp; &nbsp; &nbsp; &nbsp; Map<String, String[]> graph, String start, String target&nbsp; &nbsp; ) {&nbsp; &nbsp; &nbsp; &nbsp; Map<String, String> visited = new HashMap<>();&nbsp; &nbsp; &nbsp; &nbsp; visited.put(start, null);&nbsp; &nbsp; &nbsp; &nbsp; ArrayDeque<String> deque = new ArrayDeque<>();&nbsp; &nbsp; &nbsp; &nbsp; deque.offer(start);&nbsp; &nbsp; &nbsp; &nbsp; while (!deque.isEmpty()) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String curr = deque.poll();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (curr.equals(target)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ArrayList<String> path = new ArrayList<>();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; path.add(curr);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while (visited.get(curr) != null) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; curr = visited.get(curr);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; path.add(curr);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Collections.reverse(path);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return path;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (String neighbor : graph.get(curr)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!visited.containsKey(neighbor)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; visited.put(neighbor, curr);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; deque.offer(neighbor);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return null;&nbsp; &nbsp; }&nbsp; &nbsp; public static void main(String[] args) {&nbsp; &nbsp; &nbsp; &nbsp; Map<String, String[]> myGraph = new HashMap<>();&nbsp; &nbsp; &nbsp; &nbsp; myGraph.put(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "lava", new String[] {"sharks", "piranhas"}&nbsp; &nbsp; &nbsp; &nbsp; );&nbsp; &nbsp; &nbsp; &nbsp; myGraph.put(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "sharks", new String[] {"lava", "bees", "lasers"}&nbsp; &nbsp; &nbsp; &nbsp; );&nbsp; &nbsp; &nbsp; &nbsp; myGraph.put(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "piranhas", new String[] {"lava", "crocodiles"}&nbsp; &nbsp; &nbsp; &nbsp; );&nbsp; &nbsp; &nbsp; &nbsp; myGraph.put(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "bees", new String[] {"sharks"}&nbsp; &nbsp; &nbsp; &nbsp; );&nbsp; &nbsp; &nbsp; &nbsp; myGraph.put(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "lasers", new String[] {"sharks", "crocodiles"}&nbsp; &nbsp; &nbsp; &nbsp; );&nbsp; &nbsp; &nbsp; &nbsp; myGraph.put(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "crocodiles", new String[] {"piranhas", "lasers"}&nbsp; &nbsp; &nbsp; &nbsp; );&nbsp; &nbsp; &nbsp; &nbsp; System.out.println(BFS(myGraph, "crocodiles", "bees"));&nbsp; &nbsp; &nbsp; &nbsp; System.out.println(BFS(myGraph, "crocodiles", "crocodiles"));&nbsp; &nbsp; &nbsp; &nbsp; System.out.println(BFS(myGraph, "crocodiles", "zebras"));&nbsp; &nbsp; }}输出[crocodiles, lasers, sharks, bees][crocodiles]null解释我做出的设计决策是为了避免在图中的每个节点上复制ArrayList,而是使用成对存储节点的哈希。这样,一旦我找到了目标节点,我就会回溯我的步骤,一次性创建路径,而不是为每个节点构建一个路径,其中大部分最终都无处可去。这在空间和时间上更有效率;Python使得使用O(n)列表串联运算符很容易破坏时间复杂性。pathvisitedchildNode => parentNode[] + []使用HashMap在Java中编码也更容易,Java没有轻量级的//,可以方便地将不同类型的节点存储在队列中。要完成你在Python中将2元素列表传递到队列中所做的事情,你必须编写自己的类,使用两个ArrayDeques,或者避免泛型并使用强制转换,所有这些都很丑陋(特别是最后一个,这也是不安全的)。child => parentvisitedPairTuplestructPair我在代码中注意到的另一个问题是将 ArrayList 用作队列。列表前面的插入和删除是 O(n) 操作,因为列表中的所有元素都必须在基础数组中向前或向后移动以保持排序。Java 中的最佳队列结构是 ArrayDeque,它在两端都提供 O(1) 添加和删除,并且与 Queue 集合不同,它不是线程安全的。同样,在Python中,您会发现使用deque集合的性能最好,该集合为您的所有排队需求提供了快速操作。此外,在Python实现中,哈希中的每个键都指向一个,这是可以的,但是当列表可以时,这似乎是一个不必要的结构(你已经切换到Java中的原始数组)。如果您不操作图形而只是迭代邻居,则这似乎很理想。popleftset请注意,此代码还假定每个节点在表示图形的哈希中都有一个键,就像您的输入一样。如果您计划输入节点在哈希中可能没有键的图形,则需要确保用检查来包装该图形以避免崩溃。graph.get(curr)containsKey另一个值得一提的假设是:确保您的图形不包含 s,因为哈希依赖于指示子项没有父项并且是搜索的开始。nullvisitednull

HUWWW

您需要创建一个单独的类来保存图形的节点。这些节点不能是静态的,因为它们都有唯一的顶点。从那里开始,其余的非常相似。public class Node {&nbsp; &nbsp; public String name;&nbsp; &nbsp; public ArrayList<Node> vertices;&nbsp; &nbsp; public void addEdge(Node node) {&nbsp; &nbsp; &nbsp; &nbsp; edges.add(node);&nbsp; &nbsp; }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java