深度优先遍历和广度优先遍历

深度优先遍历

深度优先遍历(Depth-First Traversal)简称DFS。

算法思想:

  1. 首先以一个未被访问过的顶点作为起始顶点,沿当前顶点的边走到未访问过的顶点;
  2. 当没有未访问过的顶点时,则回到上一个顶点,继续试探别的顶点,直到所有的顶点都被访问过。

这里写图片描述

图:深度优先遍历示例图

如上图,采用图的深度优先遍历的话,从0号节点遍历的顺序应该是:0,1,2,3,4.

程序源代码示例:

public class DeepTravel {

    public static void main(String[] args) {    
        //图的邻接矩阵表示
        int[][] a = {
                {0,1,1,1,0},
                {1,0,1,1,1},
                {1,1,0,0,0},
                {1,1,0,0,0},
                {0,1,0,0,0}};
        //需要一个数字,来记录染色信息,染色的节点代表已经遍历
        int[] color = new int[a.length];
        System.out.println("深度优先遍历的结果为:");
        dfs(a, color, 0);
    }

    //用递归的方法进行遍历
    private static void dfs(int[][] a, int[] color, int k) {
        System.out.print(k + " ");//打印出k号节点
        color[k] = 1;//给k号节点标记为1

        for(int i = 0; i < a[k].length; i++)
            if(a[k][i] == 1 && color[i] == 0)
                dfs(a, color, i);
    }
}

程序运行结果:

深度优先遍历的结果为:
0 1 2 3 4 

广度优先遍历

广度优先搜索算法(英语:Breadth-First-Search,缩写为BFS)。

其过程检验来说是对每一层节点依次访问,访问完一层进入下一层,而且每个节点只能访问一次。

程序示例:

这里写图片描述

图:广度优先遍历示例图

如上图,,采用图的广度优先遍历的话,从0号节点遍历的顺序应该是:0,1,2,3,6,5,4

程序源代码:

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;

public class BreadthTravel {

    public static void main(String[] args) {
        //图的邻接定义
        int[][] g = {
                {0,1,1,0,0,0,0},
                {1,0,0,1,0,0,1},
                {1,0,0,0,0,1,1},
                {0,1,0,0,1,0,0},
                {0,0,0,1,0,1,1},
                {0,0,1,0,1,0,0},
                {0,1,1,0,1,0,0}};

        //广度优先遍历
        System.out.println("广度优先遍历的结果:");
        bfs(g);

    }

    private static void bfs(int[][] g) {
        ArrayList<Integer> list = new ArrayList<Integer>();//等待遍历的节点
        Set<Integer> set = new HashSet<Integer>();//已经遍历的节点
        list.add(0);//从0号节点开始遍历

        while (true) {
            //如果列表为空,则遍历完成
            if(list.isEmpty())
                break;

            int node = list.get(0);
            System.out.print(node + " ");
            set.add(node);
            list.remove(0);

            for(int i = 0; i < g[node].length; i++) {
                if(g[node][i] == 1 && set.contains(i) == false && list.indexOf(i)<0)
                    list.add(i);
            }           
        }
    }
}

程序运行结果:

广度优先遍历的结果:
0 1 2 3 6 5 4 

最短路径树

迪杰斯特拉算法简介

迪杰斯特拉算法是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法。是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题。迪杰斯特拉算法主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。

程序示例:

这里写图片描述

图:最短路径树示例拓扑

如上图,从求0号节点开始到所有节点的最短路径。

程序源代码:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class 最短路径树 {

    static class Cell{
        int node; //连接到哪个节点
        int weight; //边的权值

        public Cell(int node, int weight) {
            this.node = node;
            this.weight = weight;
        }
    }
    @SuppressWarnings("unchecked")
    public static void main(String[] args) {
        //图的邻接表
        ArrayList[] g = new ArrayList[11];      
        for(int i = 0; i < g.length; i++)
            g[i] = new ArrayList();

        g[0].add(new Cell(1, 3));
        g[0].add(new Cell(4, 1));
        g[1].add(new Cell(2, 1));
        g[1].add(new Cell(6, 3));
        g[1].add(new Cell(5, 5));
        g[1].add(new Cell(0, 3));
        g[1].add(new Cell(9, 4));
        g[2].add(new Cell(1, 1));
        g[2].add(new Cell(3, 1));
        g[2].add(new Cell(6, 7));
        g[3].add(new Cell(2, 1));
        g[3].add(new Cell(10, 2));
        g[4].add(new Cell(0, 1));
        g[4].add(new Cell(5, 2));
        g[5].add(new Cell(4, 2));
        g[5].add(new Cell(1, 5));
        g[5].add(new Cell(7, 2));
        g[5].add(new Cell(8, 3));
        g[6].add(new Cell(1, 3));
        g[6].add(new Cell(2, 3));
        g[6].add(new Cell(8, 2));
        g[6].add(new Cell(10, 1));
        g[7].add(new Cell(5, 2));
        g[8].add(new Cell(5, 3));
        g[8].add(new Cell(6, 2));
        g[9].add(new Cell(1, 4));
        g[9].add(new Cell(10, 2));
        g[10].add(new Cell(3, 2));
        g[10].add(new Cell(6, 1));
        g[10].add(new Cell(9, 2));

        //求0号节点开始的所有最小路径
        Dijkstra(g);

    }
    public static void Dijkstra(ArrayList[] g) {
        //节点号-->最小路径值
        Map<Integer, Integer> map = new HashMap<Integer, Integer>();

        while(true) {
            int min = Integer.MAX_VALUE; //最小路径值
            int min_no = -1; //对应的节点号

            //所有与0号节点邻接,并且不在集合map中的点
            for(int i = 0; i < g[0].size(); i++) {
                Cell t = (Cell) g[0].get(i);
                if(map.get(t.node) == null && t.weight < min) {
                    min_no = t.node;
                    min = t.weight;
                }
            }
            //与map中点邻接的所有不在map中的点
            Iterator it = map.keySet().iterator();
            while(it.hasNext()) {
                int k = (int)it.next();
                //集合中的点对应的最小路径的值
                int v = (int)map.get(k);
                for(int i = 0; i < g[k].size(); i++) {
                    Cell t = (Cell)g[k].get(i);
                    if(map.get(t.node) == null && t.weight + v < min) {
                        min_no = t.node;
                        min = t.weight + v;
                    }
                }
            }

            if(min < Integer.MAX_VALUE)
                map.put(min_no, min);
            else
                break;
        }
        System.out.println(map);
    }
}

程序运行结果:

{0=2, 1=3, 2=4, 3=5, 4=1, 5=3, 6=6, 7=5, 8=6, 9=7, 10=7}

猜你喜欢

转载自blog.csdn.net/qq_38265137/article/details/80317159