• 数据结构:图(2)


    一、最小生成树

    1.普利姆算法:稠密图

    图的存贮结构采用邻接矩阵.此方法是按各个顶点连通的步骤进行,需要用一个顶点集合,开始为空集,以后将以连通的顶点陆续加入到集合中,全部顶点加入集合后就得到所需的最小生成树。

    算法理解:

    Prim

    2.克鲁斯卡尔算法:稀疏图

    图的存贮结构采用边集数组,且权值相等的边在数组中排列次序可以是任意的.该方法对于边相对比较多的不是很实用,浪费时间

    算法理解:

    Kruskal

    二、最短路径

    1.Dijkstra 算法

    算法解决的是有向图中单个源点到其他顶点的最短路径问题。举例来说,如果图中的顶点表示城市,而边上的权重表示城市间开车行经的距离,Dijkstra 算法可以用来找到两个城市之间的最短路径。

    算法理解:

    Dijkstra

    2.Floyd算法

    是解决任意两点间的最短路径的一种算法,可以正確處理有向圖或负权的最短路径問題,同时也被用于计算有向图的传递闭包。

    算法理解:

    Floyd

    代码示例:

      1 ///Name:Tree
      2 ///Author:JA
      3 ///Date:2015-3-11
      4 
      5 
      6 
      7 /*
      8 * 最短路径,迪杰斯特拉算法和弗洛伊德算法(采用邻接矩阵存储)
      9 *
     10 */
     11 
     12 #include<stdio.h>  
     13 
     14 #define MAX_VERTEX_NUM 20  
     15 #define INFINITE 10000  //当做无穷大  
     16 //图的定义  
     17 typedef struct
     18 {
     19     int vertexNum;
     20     char vertex[MAX_VERTEX_NUM];
     21     int arc[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
     22 }Graph, *PGraph;
     23 
     24 //辅助数组中的元素定义  
     25 typedef struct
     26 {
     27     int distance;
     28     int path[MAX_VERTEX_NUM];
     29 }ArrayNode;
     30 
     31 
     32 //构造有向网  
     33 void createdGraph(PGraph g)
     34 {
     35     int i, j;
     36     g->vertexNum = 6;
     37     for (i = 0; i<g->vertexNum; i++)
     38         g->vertex[i] = 'A' + i;
     39     for (i = 0; i<g->vertexNum; i++)
     40     for (j = 0; j<g->vertexNum; j++)
     41         g->arc[i][j] = 0;
     42     g->arc[0][2] = 10;
     43     g->arc[0][4] = 30;
     44     g->arc[0][5] = 100;
     45     g->arc[1][2] = 5;
     46     g->arc[2][3] = 50;
     47     g->arc[3][5] = 10;
     48     g->arc[4][3] = 20;
     49     g->arc[4][5] = 60;
     50 }
     51 
     52 //迪杰斯特拉算法  
     53 void Dijkstra(PGraph g, int from, int to)
     54 {
     55     int i, j, index = -1;
     56     int n = 1;//记录已经求出的两个点之间的最短距离的个数  
     57     ArrayNode shortestPath[MAX_VERTEX_NUM];
     58     int flag[MAX_VERTEX_NUM] = { 0 };//标记,为1表示到这个顶点的最短距离已求出  
     59 
     60     //1.求from到各个顶点的直接距离,即初始化shortestPath数组  
     61     for (i = 0; i<g->vertexNum; i++){
     62         if (from == i){
     63             shortestPath[i].distance = 0;
     64             shortestPath[i].path[0] = i;
     65             flag[from] = 1;
     66         }
     67         else if (g->arc[from][i]>0){
     68             shortestPath[i].path[0] = from;
     69             shortestPath[i].path[1] = i;
     70             shortestPath[i].distance = g->arc[from][i];
     71         }
     72         else
     73             shortestPath[i].distance = INFINITE;
     74     }
     75     //2.每次求一个最短路径  
     76     while (n<g->vertexNum){
     77         //选择shortestPath中距离最小的,求出from到这个顶点的最短路径  
     78         index = -1;
     79         for (i = 0; i<g->vertexNum; i++){
     80             if (i == from)
     81                 continue;
     82             if (flag[i] == 0 && index == -1 && shortestPath[i].distance != INFINITE)
     83                 index = i;
     84             if (flag[i] == 0 && index != -1 && shortestPath[i].distance<shortestPath[index].distance)
     85                 index = i;
     86         }
     87         flag[index] = 1;
     88         //修改到各个顶点的最短路径  
     89         for (i = 0; i<g->vertexNum; i++){
     90             if (i == from)
     91                 continue;
     92             if (g->arc[index][i]>0 && g->arc[index][i] + shortestPath[index].distance<shortestPath[i].distance){
     93                 shortestPath[i].distance = g->arc[index][i] + shortestPath[index].distance;
     94                 //修改路径  
     95                 j = 0;
     96                 while (1){
     97                     shortestPath[i].path[j] = shortestPath[index].path[j];
     98                     if (shortestPath[index].path[j] == index)
     99                         break;
    100                     j++;
    101                 }
    102                 shortestPath[i].path[j + 1] = i;
    103             }
    104         }
    105         n++;
    106     }
    107     //输出from到to的最短路径及长度  
    108     if (shortestPath[to].distance == INFINITE){
    109         printf("%c到%c没有路径
    ", from + 'A', to + 'A');
    110         return;
    111     }
    112     printf("%c到%c的最短路径长度是:%d
    ", from + 'A', to + 'A', shortestPath[to].distance);
    113     printf("经过的顶点:  ");
    114     i = 0;
    115     while (1){
    116         printf("%-3c", shortestPath[to].path[i] + 'A');
    117         if (shortestPath[to].path[i] == to)
    118             break;
    119         i++;
    120     }
    121     printf("
    ");
    122 }
    123 
    124 //弗洛伊德算法  
    125 void Floyd(PGraph g, int from, int to)
    126 {
    127     int i, j, k;
    128     int shortestPath[MAX_VERTEX_NUM][MAX_VERTEX_NUM];//存储最短路径的数组  
    129     //初始化shortestPath  
    130     for (i = 0; i<g->vertexNum; i++)
    131     for (j = 0; j<g->vertexNum; j++){
    132         if (i == j){
    133             shortestPath[i][j] = 0;
    134             continue;
    135         }
    136         if (g->arc[i][j]>0)
    137             shortestPath[i][j] = g->arc[i][j];
    138         else
    139             shortestPath[i][j] = INFINITE;
    140     }
    141     //将各个顶点顺次加入,并修改最短路径  
    142     for (k = 0; k<g->vertexNum; k++){
    143         //在i,j之间加入k  
    144         for (i = 0; i<g->vertexNum; i++){
    145             for (j = 0; j<g->vertexNum; j++){
    146                 if (shortestPath[i][k] + shortestPath[k][j]<shortestPath[i][j])
    147                     shortestPath[i][j] = shortestPath[i][k] + shortestPath[k][j];
    148             }
    149         }
    150     }
    151     //输出最短路径  
    152     if (shortestPath[from][to] == INFINITE){
    153         printf("%c到%c没有路径
    ", from + 'A', to + 'A');
    154         return;
    155     }
    156     printf("%c到%c的最短路径长度是:%d
    ", from + 'A', to + 'A', shortestPath[from][to]);
    157     printf("
    ");
    158 }
    159 
    160 void main()
    161 {
    162     Graph graph;
    163     char from, to;
    164     createdGraph(&graph);
    165     printf("请输入起点终点(如AF,中间不要有空格)
    ");
    166     scanf("%c%c", &from, &to);
    167     printf("
    迪杰斯特拉算法:
    ");
    168     Dijkstra(&graph, from - 'A', to - 'A');
    169     printf("
    弗洛伊德算法:
    ");
    170     Floyd(&graph, from - 'A', to - 'A');
    171 }
    View Code

    3/12/2015 2:12:53 PM

  • 相关阅读:
    LiveCharts文档-3开始-1安装
    LiveCharts文档-2FAQ
    时间戳的简介
    LiveCharts文档-1前言
    做了一个串口读写温度的程序
    CsvHelper文档-6类型转换
    CsvHelper文档-5配置
    如何选择 .NET Framework目标版本
    CsvHelper文档-4映射
    CsvHelper文档-3写
  • 原文地址:https://www.cnblogs.com/joeaaron007/p/4332453.html
Copyright © 2020-2023  润新知