zoukankan      html  css  js  c++  java
  • 普里姆算法

    //普里姆算法
    //构造连通网的最小代价生成树
    /*
    基本思路:
        1. 任选一个结点,任选一个作为这棵树的起点。
        2. 找出所有与当前树中叶子结点连接的边,找出权最小的一条边,
             将这条边的另一个端点加入到树中。
        3. 重复2的操作,直到连接所有结点。
    重点:
        1.lowcost数组里保存的是与“当前树中所有叶子节点”有连线的未加入树的结点
        2.adjvex数组:体会函数中的“printf("(%d, %d)
    ", adjvex[k], k);”
    */
    #include <stdio.h>
    #define MAXNUM 9                 //顶点的最大数量
    #define INFINITY 65535
    
    typedef struct {
        char vexs[MAXNUM];             //包含所有顶点的数组
        int arc [MAXNUM][MAXNUM];      //邻接矩阵
        int numVertexes, numEdges;      //当前图中的顶点数量和边的数量
    } Graph;
    
    //建立无向图的邻接矩阵
    void CreatGraph(Graph* G) {
        int i, j;
    /*
        printf("请输入顶点数和边数");
        scanf("%d", &G->numVertexes);
        scanf("%d", &G->numEdges);
    
        for (i = 0; i < G->numVertexes; i++)
            for (j = 0; j < G->numVertexes; j++)
                G->arc[i][j] = INFINITY;
    
        for (k = 0; k < G->numEdges; k++) {
            printf("请输入边在邻接矩阵中的横纵坐标和权值:");
            fflush(stdin);
            scanf("%d", &i);
            scanf("%d", &j);
            scanf("%d", &w);
            G->arc[i][j] = w;
            G->arc[j][i] = G->arc[i][j];
        }
    */
        G->numVertexes = 9;
        G->numEdges = 15;
    
        for (i = 0; i < G->numVertexes; i++)
            for (j = 0; j < G->numVertexes; j++) {
                if (i == j)
                    G->arc[i][j]=0;
                else
                    G->arc[i][j] = INFINITY;
            }
        G->arc[0][1]=10;
        G->arc[0][5]=11;
        G->arc[1][2]=18;
        G->arc[1][8]=12;
        G->arc[1][6]=16;
        G->arc[2][8]=8;
        G->arc[2][3]=22;
        G->arc[3][8]=21;
        G->arc[3][6]=24;
        G->arc[3][7]=16;
        G->arc[3][4]=20;
        G->arc[4][7]=7;
        G->arc[4][5]=26;
        G->arc[5][6]=17;
        G->arc[6][7]=19;
    
        for(i = 0; i < G->numVertexes; i++) {
                for(j = i; j < G->numVertexes; j++) {
                    G->arc[j][i] =G->arc[i][j];
                }
            }
    
        printf("
    该邻接矩阵是
    ");
        for (i = 0; i < G->numVertexes; i++) {
            for (j = 0; j < G->numVertexes; j++)
                printf("%5d ", G->arc[i][j]);
            printf("
    ");
        }
    
    }
    
    //普里姆算法生成最小生成树
    void MiniSpanTree_Prim(Graph G) {
        int min, i, j, k;
        int lowcost[MAXNUM];//保存相关顶点之间边的权值
        int adjvex[MAXNUM];//保存相关顶点下标
        lowcost[0] = 0;
        adjvex[0] = 0;//第一个顶点下标为0
        for (i = 1; i < G.numVertexes; i++) {//循环搜索除下标0外的全部顶点
            lowcost[i] = G.arc[0][i];//将与V0顶点有关的顶点的边的权值存入数组
            adjvex[i] = 0;//全部初始化为0的下标
        }
    
        for (i = 1; i < G.numVertexes; i++) {
            min = INFINITY;//将最小值初始化为“无限大”
            j = 1; k = 0;
            //这个while循环最终找到的是与当前叶节点距离最近的顶点的下标值(存入k)
            while (j < G.numVertexes) {
                if (lowcost[j]!=0 && lowcost[j]<min) {
                    min = lowcost[j];
                    k = j;
                }
                j++;
            }
            //在最小生成树中,adjvex[k]节点为k节点的父节点
            printf("(%d, %d)
    ", adjvex[k], k);
            lowcost[k] = 0;//此顶点已在树中了,所以不再考虑它了
            for (j = 1; j < G.numVertexes; j++) {
                if (lowcost[j]!=0 && G.arc[k][j] < lowcost[j]) {
                    lowcost[j] = G.arc[k][j];
                    adjvex[j] = k;
            //注意:意思是新加入候选节点的j节点(们)是当前加入树的k节点的孩子节点
                }
            }
        }
    }
    int main()
    {
        Graph G;
        CreatGraph(&G);
        MiniSpanTree_Prim(G);
    
        return 0;
    }
    
  • 相关阅读:
    DOM对象的一些常用方法
    body-parser的使用
    CSS中box-sizing: border-box
    ES6 数组方法 --- map() filter() find()的用法
    JavaScript --- 预编译
    Vue过滤器filter
    Lock wait timeout exceeded; try restarting transaction
    lead函数
    Mysql 数据词典
    OOD
  • 原文地址:https://www.cnblogs.com/qianbixin/p/4998347.html
Copyright © 2011-2022 走看看