广度优先搜索算法(java和php对比)

2019-05-02  本文已影响0人  小伟_be27

java实现:

public class BFS {
    
        public static void main(String[] args){
            //初始化先建立起各个节点信息,以及对应的直接子节点列表
            HashMap<String,String[]> map = new HashMap<>();
            map.put("A", new String[] {"B","C"});
            map.put("B", new String[] {"E"});
            map.put("C", new String[] {"D","F"});
            map.put("D", new String[] {"E"});
            map.put("E", new String[] {"H"});
            map.put("F", new String[] {"E","G"});
            map.put("G", new String[] {"H"});
            map.put("H", new String[] {});
            //获取从A到H的最短路径节点链表
            Node target = findTarget("A","H",map);
            //打印出最短路径的各个节点信息
            printSearPath(target);
    
        }
    
        /**
         * 打印出到达节点target所经过的各个节点信息
         * @param target
         */
        static void printSearPath(Node target) {
            if (target != null) {
                System.out.print("找到了目标节点:" + target.id + "\n");
                
                List<Node> searchPath = new ArrayList<Node>();
                searchPath.add(target);
                Node node = target.parent;
                while(node!=null) {
                    searchPath.add(node);
                    node = node.parent;
                }
                String path = "";
                for(int i=searchPath.size()-1;i>=0;i--) {
                    path += searchPath.get(i).id;
                    if(i!=0) {
                        path += "-->";
                    }
                }
                System.out.print("步数最短:"+path);
            } else {
                System.out.print("未找到了目标节点");
            }
        }
        
        /**
         * 从指定的开始节点 startId ,查询到目标节点targetId 的最短路径
         * @param startId
         * @param targetId
         * @param map
         * @return
         */
        static Node findTarget(String startId,String targetId,HashMap<String,String[]> map) {
            List<String> hasSearchList = new ArrayList<String>();
            LinkedList<Node> queue = new LinkedList<Node>();
            queue.offer(new Node(startId,null));
            while(!queue.isEmpty()) {
                Node node = queue.poll();
                
                if(hasSearchList.contains(node.id)) {
                    //跳过已经搜索过的,避免重复或者死循环
                    continue;
                }
                System.out.print("判断节点:" + node.id +"\n");
                if (targetId.equals(node.id)) {
                    return node;
                }
                hasSearchList.add(node.id);
                if (map.get(node.id) != null && map.get(node.id).length > 0) {
                    for (String childId : map.get(node.id)) {
                        queue.offer(new Node(childId,node));
                    }
                }
            }
    
            return null;
        }
        
        /**
         * 节点对象
         * @author Administrator
         *
         */
        static class Node{
            //节点唯一id
            public String id;
            //该节点的直接父节点
            public Node parent;
            //该节点的直接子节点
            public List<Node> childs = new ArrayList<Node>();
            public Node(String id,Node parent) {
                this.id = id;
                this.parent = parent;
            }
        }
    
    }

执行结果:

判断节点:A
    判断节点:B
    判断节点:C
    判断节点:E
    判断节点:D
    判断节点:F
    判断节点:H
    找到了目标节点:H
    步数最短:A-->B-->E-->H

php实现:

$arr = [
    'A' => ['B','C'],
    'B' => ['E'],
    'C' => ['D','F'],
    'D' => ['E'],
    'E' => ['H'],
    'F' => ['E,G']
];
//求 A -> F的最短路径
function BFS($arr,$start,$target){
    $queue = $arr[$start];   //节点队列
    $path = [];              //记录最短路径
    foreach($arr[$start] as $val){
        $path[$val] = $start;
    }      
    $searched = [];          //标记已经访问过的节点
    while(!empty($queue)){
        $head = array_shift($queue);
        if($head == $target){    //找到目标
            break;
        }         
        if(in_array($head,$searched)){  //已经访问过,直接跳过 
            continue;     
        }
        $searched[] = $head;
        foreach($arr[$head] as $val){
            $path[$val] = $head;
        }
        $queue = array_merge($queue,$arr[$head]);
    }
   
    $pathto = [];
    while(!empty($path[$target])){
        $pathto[] = $target;
        $target = $path[$target];
    }
    $pathto[] = $target;
    $pathstr = "";
    for($i = count($pathto) -1 ;$i >=0;$i--){
        $pathstr .= $pathto[$i]."->";
    }
    $pathstr = substr($pathstr,0,strlen($pathstr)-2);
    echo "min path:".$pathstr;
}


BFS($arr,'A','F');
min path:A->C->D
上一篇 下一篇

猜你喜欢

热点阅读