• 重新整理数据结构与算法(c#)——算法套路迪杰斯特拉算法[三十一]


    前言

    迪杰斯特拉算法 是求最短路径方法的其中一种,这个有什么作用呢?

    有一张图:

    假设求G点到其他各点的最小路径。

    是这样来的。

    比如找到了和G点相连接所有点,ABED。这时候确定GA是一定是最短的,为什么这么说呢?G->A和G从别的点到A,一旦G走BED 一定会大于GA,后续就跟不可能大于了。

    所以GA为最短,这时候就确定了A。这时候开始从A点开始,找到和A点相连但是没有确定最短的点,有B、C。G->A->B 大于G->B。然后A可以到C,这时候确定G->C 是9。

    然后从G到各点已经相连中,找到没有确认的最小路径,这个就是确认了G->B最短。为什么能够确认呢?因为G到A然后到B大于G->B,那么可以确认G到B最短,这是因为GA是最短的,从最短的到不了,其他的一定大于G->B。

    上面说其实有点模糊。

    是这样的,如果从G为出发点确认了n个点,那么剩下的m个点怎么确认呢?

    肯定就是从G从到先到G最短的点,尝试是否有其他路,如果没有,那么就确认了。

    正文

    代码如下:

    class Program
    {
    	private static int INF = int.MaxValue;
    
    	static void Main(string[] args)
    	{
    		char[] vertex = { 'A', 'B', 'C', 'D', 'E', 'F', 'G' };
    		int N = 65535;// 表示不可以连接
    		int[,] matrix = { { N, 5, 7, N, N, N, 2 },
    		{ 5, N, N, 9, N, N, 3 },
    		{ 7, N, N, N, 8, N, N },
    		{ N, 9, N, N, N, 4, N },
    		{ N, N, 8, N, N, 5, 4 },
    		{ N, N, N, 4, 5, N, 6 },
    		{ 2, 3, N, N, 4, 6, N }
    		};
    		//创建 Graph对象
    		Graph graph = new Graph(vertex, matrix);
    		//测试, 看看图的邻接矩阵是否ok
    		graph.showGraph();
    		//测试迪杰斯特拉算法
    		graph.dsj(2);//C
    		graph.showDijkstra();
    		Console.Read();
    	}
    }
    class Graph
    {
    	private char[] vertex;//顶点数组
    	private int[,] matrix;//邻接矩阵
    	private VisitedVertex vv;//顶点状态
    	public Graph(char[] vertex, int[,] matrix)
    	{
    		this.vertex = vertex;
    		this.matrix = matrix;
    	}
    
    	public void showDijkstra()
    	{
    		vv.show();
    	}
    
    	public void showGraph()
    	{
    		for (int i = 0; i < vertex.Length; i++)
    		{
    			for (int j = 0; j < vertex.Length; j++)
    			{
    				Console.Write(matrix[i, j] + "  ");
    			}
    			Console.WriteLine();
    		}
    	}
    
    	public void dsj(int index)
    	{
    		vv = new VisitedVertex(vertex.Length, index);
    		update(index);
    		for (int i = 1; i < vertex.Length; i++)
    		{
    			index = vv.updateArr();
    			update(index);
    		}
    	}
    
    	private void update(int index)
    	{
    		int len = 0;
    		for (int j = 0; j < vertex.Length; j++)
    		{
    			len = vv.getDis(index) + matrix[index, j];
    			if (!vv.isVisited(j) && len < vv.getDis(j))
    			{
    				vv.updatePre(j, index);
    				vv.updateDis(j, len);
    			}
    		}
    	}
    }
    class VisitedVertex
    {
    
    	//记录各个顶点的访问状态
    	public int[] already_arr;
    	//每个顶点对应前一个顶点的下标
    	public int[] pre_visited;
    	//记录出发点到其他顶点的距离
    	public int[] dis;
    
    	public VisitedVertex(int length, int index)
    	{
    		already_arr = new int[length];
    		pre_visited = new int[length];
    		dis = new int[length];
    		Array.Fill(dis, int.MaxValue);
    		this.already_arr[index] = 1;
    		this.dis[index] = 0;
    	}
    
    	public int updateArr()
    	{
    		int min = int.MaxValue, index = 0;
    		for (int i = 0; i < already_arr.Length; i++)
    		{
    			if (already_arr[i] == 0 && dis[i] < min)
    			{
    				min = dis[i];
    				index = i;
    			}
    		}
    		//更新 index 顶点被访问过
    		already_arr[index] = 1;
    		return index;
    	}
    	/// <summary>
    	/// 是否访问过
    	/// </summary>
    	/// <param name="index">下标距离</param>
    	/// <returns></returns>
    	public Boolean isVisited(int index)
    	{
    		return already_arr[index] == 1;
    	}
    	//更新距离
    	public void updateDis(int index, int length)
    	{
    		dis[index] = length;
    	}
    
    	//更新前驱节点
    	public void updatePre(int index, int pre)
    	{
    		pre_visited[index] = pre;
    	}
    	//返回到某个节点的距离
    	public int getDis(int index)
    	{
    		return dis[index];
    	}
    	//显示最后的结果
    	//即将三个数组的情况输出
    	public void show()
    	{
    		Console.WriteLine("输出前驱");
    		//输出pre_visited
    		foreach (int i in pre_visited)
    		{
    			Console.Write(i + " ");
    		}
    		Console.WriteLine();
    		char[] vertex = { 'A', 'B', 'C', 'D', 'E', 'F', 'G' };
    		int count = 0;
    		foreach (int i in dis)
    		{
    			if (i != 65535)
    			{
    				Console.Write(vertex[count] + "(" + i + ") ");
    			}
    			else
    			{
    				Console.Write("N ");
    			}
    			count++;
    		}
    		Console.WriteLine();
    	}
    }
    

    结果:

  • 相关阅读:
    [udemy]WebDevelopment_HTML5
    [udemy]WebDevelopment_History of The Web
    [udemy]WebDevelopment_How the Internet Works
    [leetcode]340. Longest Substring with At Most K Distinct Characters至多包含K种字符的最长子串
    用Maven创建web项目
    spring mvc3 静态文件放在WEB-INF下无法访问解决和解决@Controller失效问题
    整合spring+mybatis遇到的问题01
    The content of element type "configuration" must match "(properties?,settings?,typeAliases?,typeHandlers?,objectFactory?...
    导出EXCEL遇到问题
    Result Maps collection does not contain value for...
  • 原文地址:https://www.cnblogs.com/aoximin/p/13340068.html
Copyright © 2020-2023  润新知