zoukankan      html  css  js  c++  java
  • 数据结构【图】—024最小生成树

    /*****************************普里姆(Prim)算法***************************/

    /*
    此为无向图
    Prim算法思想很简单,依托临接矩阵
    就是从顶点0开始,依次比较起始点到下一个点的最短路径,并将其更新
    然后以新的点为起始点,再找到该点能够到达的下一个最短路径,
    直到所有点都遍历完为止!
    */

    根据程序,最小线段生成如下:

     1 #include "000库函数.h"
     2 
     3 #define MAXVEX 20
     4 #define INFINITY 65535//视为无穷大
     5 
     6 //临接矩阵的数据结构
     7 struct MGraph {
     8     int arc[MAXVEX][MAXVEX];
     9     int numVertexes, numEdges;
    10 };
    11 
    12 //初始化临接矩阵
    13 MGraph *CreateMGraph(MGraph *G) {
    14     G->numEdges = 15;
    15     G->numVertexes = 9;
    16 
    17     for (int i = 0; i < G->numVertexes; i++)/* 初始化图 */
    18     {
    19         for (int j = 0; j < G->numVertexes; j++)
    20         {
    21             if (i == j)
    22                 G->arc[i][j] = 0;
    23             else
    24                 G->arc[i][j] = G->arc[j][i] = INFINITY;
    25         }
    26     }
    27 
    28     G->arc[0][1] = 10;
    29     G->arc[0][5] = 11;
    30     G->arc[1][2] = 18;
    31     G->arc[1][8] = 12;
    32     G->arc[1][6] = 16;
    33     G->arc[2][8] = 8;
    34     G->arc[2][3] = 22;
    35     G->arc[3][8] = 21;
    36     G->arc[3][6] = 24;
    37     G->arc[3][7] = 16;
    38     G->arc[3][4] = 20;
    39     G->arc[4][7] = 7;
    40     G->arc[4][5] = 26;
    41     G->arc[5][6] = 17;
    42     G->arc[6][7] = 19;
    43 
    44     for (int i = 0; i < G->numVertexes; i++)
    45     {
    46         for (int j = i; j < G->numVertexes; j++)
    47         {
    48             G->arc[j][i] = G->arc[i][j];
    49         }
    50     }
    51     return G;
    52 }
    53 
    54 //使用Prim算法生成最小树
    55 void MiniSpanTree_Prim(MGraph *G) {
    56     int min, i, j, k;
    57     int adjvex[MAXVEX];//保存相关顶点的下标
    58     int lowcost[MAXVEX]; // 保存相关顶点间边的权值
    59     lowcost[0] = 0;//将v0顶点加入进来
    60     adjvex[0] = 0;//初始化第一个顶点为0
    61     for (int i = 1; i < G->numVertexes; ++i) {
    62         lowcost[i] = G->arc[0][i];//先将v0能到其他点的距离记录下来
    63         adjvex[i] = 0;//即到达每个点的起始点都为0点
    64     }
    65 
    66     for (int i = 1; i < G->numVertexes; ++i) {
    67         min = INFINITY;//将最短路径设为无穷
    68         j = 1; k = 0;
    69         while (j < G->numVertexes) {
    70             if (lowcost[j] != 0 && lowcost[j] < min) {//找到点0到下一个距离最短的值
    71                 min = lowcost[j];//
    72                 k = j;//记住最小值的点
    73             }
    74             ++j;
    75         }
    76 
    77         printf("(%d, %d)
    ", adjvex[k], k);
    78         lowcost[k] = 0;//重新以点k为起始点,然后继续寻找下一个最短路径
    79         for (j = 1; j < G->numVertexes; ++j) {
    80             if (lowcost[j] != 0 && G->arc[k][j] < lowcost[j]) {//找到下一个最短路劲
    81                 lowcost[j] = G->arc[k][j];
    82                 adjvex[j] = k;
    83             }
    84         }
    85 
    86     }
    87 }
    88 
    89 int T025(void){
    90     MGraph *G;
    91     G = new MGraph;//初始化图
    92     G = CreateMGraph(G);
    93     MiniSpanTree_Prim(G);
    94 
    95     return 0;
    96 
    97 }

      

    /************************克鲁斯卡尔(Kruskal)******************/

    根据权值大小,生成权值表,然后根据权值表进行探索路径

      1 #include "000库函数.h"
      2 
      3 #define MAXVEX 20
      4 #define INFINITY 65535//视为无穷大
      5 
      6 //临接矩阵的数据结构
      7 struct MGraph {
      8     int arc[MAXVEX][MAXVEX];
      9     int numVertexes, numEdges;
     10 };
     11 
     12 //初始化临接矩阵
     13 MGraph *CreateMGraph(MGraph *G) {
     14     G->numEdges = 15;
     15     G->numVertexes = 9;
     16 
     17     for (int i = 0; i < G->numVertexes; i++)/* 初始化图 */
     18     {
     19         for (int j = 0; j < G->numVertexes; j++)
     20         {
     21             if (i == j)
     22                 G->arc[i][j] = 0;
     23             else
     24                 G->arc[i][j] = G->arc[j][i] = INFINITY;
     25         }
     26     }
     27 
     28     G->arc[0][1] = 10;
     29     G->arc[0][5] = 11;
     30     G->arc[1][2] = 18;
     31     G->arc[1][8] = 12;
     32     G->arc[1][6] = 16;
     33     G->arc[2][8] = 8;
     34     G->arc[2][3] = 22;
     35     G->arc[3][8] = 21;
     36     G->arc[3][6] = 24;
     37     G->arc[3][7] = 16;
     38     G->arc[3][4] = 20;
     39     G->arc[4][7] = 7;
     40     G->arc[4][5] = 26;
     41     G->arc[5][6] = 17;
     42     G->arc[6][7] = 19;
     43 
     44     for (int i = 0; i < G->numVertexes; i++)
     45     {
     46         for (int j = i; j < G->numVertexes; j++)
     47         {
     48             G->arc[j][i] = G->arc[i][j];
     49         }
     50     }
     51     return G;
     52 }
     53 
     54 //寻找下一个顶点位置
     55 int Find(vector<int>parent, int v) {
     56     while (parent[v] > 0)v = parent[v];
     57     return v;
     58 }
     59 
     60 
     61 //使用MiniSpanTree_Kruskal生成最小树
     62 void MiniSpanTree_Kruskal(MGraph *G) {
     63     int n, m;
     64     int k = 0;
     65     vector<int> Parent(MAXVEX, 0);//定义一个数组,用来判断是否形成了环路
     66     int Edge[MAXVEX][3];//权值表,存放起始点、终止点、权值
     67     //构建权值表
     68     for (int i = 0; i < G->numVertexes; ++i) {
     69         for (int j = i + 1; j < G->numVertexes; ++j) {
     70             if (G->arc[i][j] < INFINITY) {
     71                 Edge[k][0] = i;
     72                 Edge[k][1] = j;
     73                 Edge[k][2] = G->arc[i][j];
     74                 k++;
     75             }
     76         }
     77     }
     78     //进行排序
     79     for (int i = 0; i < k; ++i) {
     80         int min = Edge[i][2];
     81         for (int j = i + 1; j < k; ++j) {
     82             if (min > Edge[j][2]) {
     83                 min = Edge[j][2];
     84                 for (int t = 0; t < 3; ++t) {
     85                     int temp;
     86                     temp = Edge[i][t];
     87                     Edge[i][t] = Edge[j][t];
     88                     Edge[j][t] = temp;
     89                 }
     90             }
     91         }
     92     }
     93 
     94 
     95     /*************************算法的核心*****************************/
     96 
     97 
     98 
     99 
    100     int adjvex[MAXVEX];//保存相关顶点的下标
    101     int lowcost[MAXVEX]; // 保存相关顶点间边的权值
    102     lowcost[0] = 0;//将v0顶点加入进来
    103     adjvex[0] = 0;//初始化第一个顶点为0
    104     for (int i = 1; i < G->numVertexes; ++i) {
    105         lowcost[i] = G->arc[0][i];//先将v0能到其他点的距离记录下来
    106         adjvex[i] = 0;//即到达每个点的起始点都为0点
    107     }
    108 
    109     for (int i = 0; i < k; ++i) {//循环每一个权值矩阵
    110         n = Find(Parent, Edge[i][0]);
    111         m = Find(Parent, Edge[i][1]);
    112         if (n != m) {//不会形成环,可以使用
    113             Parent[n] = m;
    114             cout << Edge[i][0] << "," << Edge[i][1] << endl;
    115         }
    116     }
    117 }
    118 
    119     
    120 
    121 int T026(void) {
    122     MGraph *G;
    123     G = new MGraph;//初始化图
    124     G = CreateMGraph(G);
    125     MiniSpanTree_Kruskal(G);
    126 
    127     return 0;
    128 
    129 }
  • 相关阅读:
    cout的输出格式初探
    CVPR 2015 papers
    C语言的32个保留字
    读取siftgeo格式文件的matlab程序
    (转)各类排序算法总结
    被除数、除数、商、余数的正负号规律二
    被除数、除数、商、余数的正负号规律一
    FCKEditor上传图片word
    CKEditor上传图片word
    在线编辑器上传图片word
  • 原文地址:https://www.cnblogs.com/zzw1024/p/10581682.html
Copyright © 2011-2022 走看看