Minimal connectivity-(code, analysis, assembly)

Introduction:

A spanning tree of a connected graph with n nodes is a minimal connected subgraph of the original graph, and contains all n nodes in the original graph,
and has the fewest edges that keep the graph connected.
The minimum spanning tree can be obtained by kruskal algorithm or prim algorithm

Prim's algorithm, an algorithm in graph theory, can search for the minimum spanning tree in a weighted connected graph.
In the tree formed by the subset of edges searched by this algorithm, not only all vertices in the connected graph are included, but all edges have the smallest weight

Code:

#include <stdio.h>
#include <stdlib.h>

/*
程序描述:
矩阵有多行数据,cost数组从矩阵中提取数据,P记录cost数组的数据分别属于矩阵的哪一行
Mark记录在cost不再进行比较数据的下标(已经是最小值当前cost中最小值的下标了)
在cost数组中找出最小值与其在cost中的下标,再将该下标在mark中标记,下次不再处理这个位置
当前cost比较完成后,用找到的最小值作为下一行要提取数据的行号,然后用该行的数据与cost中的数据
比较,取每个位置较小值,除了已经标记的位置不进行提取。并修改P中对应较小值属于行
更新cost和P后,再进行在cost中找最小值同样的操作,依次循环整个矩阵
*/

#define VNUM 9
#define MV 65536

int P[VNUM];//存储要当前比较的数据是属于哪一行的
int Cost[VNUM];//要用于比较的数据的数组
int Mark[VNUM];//记录列状态,标记为1的列,将不再处理比较
int Matrix[VNUM][VNUM] =    //n行与n列数据一样的矩阵
{
    
    
    {
    
    0, 10, MV, MV, MV, 11, MV, MV, MV},
    {
    
    10, 0, 18, MV, MV, MV, 16, MV, 12},
    {
    
    MV, 18, 0, 22, MV, MV, MV, MV, 8},
    {
    
    MV, MV, 22, 0, 20, MV, MV, 16, 21},
    {
    
    MV, MV, MV, 20, 0, 26, MV, 7, MV},
    {
    
    11, MV, MV, MV, 26, 0, 17, MV, MV},
    {
    
    MV, 16, MV, MV, MV, 17, 0, 19, MV},
    {
    
    MV, MV, MV, 16, 7, MV, 19, 0, MV},
    {
    
    MV, 12, 8, 21, MV, MV, MV, MV, 0},
};
//cost 先取第一行的数据开始比较
void Prim(int sv) // O(n*n)
{
    
    
    int i = 0;
    int j = 0;
    
    if( (0 <= sv) && (sv < VNUM) )//判断sv在矩阵范围内
    {
    
    
        for(i=0; i<VNUM; i++)
        {
    
    
            Cost[i] = Matrix[sv][i];//将sv行所有列赋到cost,表示从sv行的数据开始处理比较
            P[i] = sv;//将P全部赋0,表示当前所有数据属于0行的
            Mark[i] = 0;//Mark数组全赋0,初始化
        }
        
        Mark[sv] = 1;//将0列设为1,刚开始0列不处理比较
        
        for(i=0; i<VNUM; i++)
        {
    
    
            int min = MV;
            int index = -1;
            
            for(j=0; j<VNUM; j++)
            {
    
    
                //从没有被标记数据中取值,找出cost(当前要比较的数据)中最小值和其在cost中的下标
                if( !Mark[j] && (Cost[j] < min) )
                {
    
    
                    min = Cost[j];//给最小值赋值  
                    index = j;//最小值的下标  
                }
            }
            
            if( index > -1 )//表示执行了上面,找到了最小值
            {
    
    
                Mark[index] = 1;  //将该下标进行标记,下次不再比较该列的数据
                
                printf("(%d, %d, %d)\n", P[index], index, Cost[index]); // 输出这次查找出最小值位于的行与下标与数值
            }
            
            for(j=0; j<VNUM; j++) //循环找出下一次用比较的数据
            {
    
    
				//从上次找到的最小值的下标,作为重新提取数据的行
				//只要不是被标记的列,从行中提取的数据比原来比较的数据小就取行中的数和下标
				//也用新的一行中的数据与本来用于比较的数据取对应位置较小的一方,并将该位置的值属于
				//哪一行中提取出来的,存到P中
                if( !Mark[j] && (Matrix[index][j] < Cost[j]) ) //更新到cost数组
                {
    
    
                    Cost[j]  = Matrix[index][j];//更新用来比较数据数组
                    P[j] = index;//更新数据属于的行
                }
				
            }
			
        }
    }
}

int main(int argc, char *argv[]) 
{
    
    
   Prim(0);
    
	
	getchar();
	return 0;
}

analysis:

Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here

compilation:

Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here

Guess you like

Origin blog.csdn.net/m0_37599645/article/details/112168845