首页 > 编程语言 >从零开始学数据结构系列之第四章《prim算法(普里姆算法)总代码》

从零开始学数据结构系列之第四章《prim算法(普里姆算法)总代码》

时间:2024-07-23 12:54:53浏览次数:16  
标签:index prim weight min int MAX edge 算法 从零开始

文章目录


回顾

我们用这张图来进行算法讲解
在这里插入图片描述

初始化

/*
* vex  - 存储顶点
* weight - 存储权值
*/
typedef struct Edge {
    char vex;
    int weight;
}Edge;

/*
* 开辟数组大小得空间,大小具体为 vexNum 的个数
* 同时将 vex 初始化赋值同G->vexs 一样,这里的vex全都是一样的值,等后续进行更新
* weight的值为index行的那一列二维数组的值
* 按总代码来讲,如果传入值为 index= 0, 则 T[i].weight初始化成0, 6, 1, 5, MAX, MAX这一关于顶点“1”的所有边的权值
如果传入值为 index= 1, 则 T[i].weight初始化成6, 0, 5, MAX, 3, MAX,这一关于顶点“2”的所有边的权值,以此类推
*
* 总的来说初始化同时将传入进来的顶点也初始化了
*/

Edge* initEdeg(Graph* G, int index) 
{
	int i=0;
	Edge *T   =	(Edge*)malloc(sizeof(Edge) * G->vexNum);
	for(i=0;i<G->vexNum;i++)
	{
		T[i].vex = G->vexs[index];
		T[i].weight = G->arcs[index][i];
	}
	return T;
}

寻找最小权值

/*
*	我们规定,如果他的weight为0时,说明他已经访问过了这个节点/或者是他本身了
*	同时不断找到最小值并且逐步开始更新min的值,知道找到这一顶点这一条边的最小权值
*/

int getMinEdge(Edge* edge, Graph* G)
{
	int min = MAX;
	int i=0;
	int index=0;
	for(i=0;i<G->vexNum;i++)
	{
		if(edge[i].weight && edge[i].weight < min)
		{		
			min = edge[i].weight;
			index = i;
		}
	}
	return index;
}

算法主体

/*
*	初始化顶点的值,所以我们在循环的时候就要G->vexNum-1。这里减去的就是顶点的值
*	循环获取最小值,同时获取完最小值以后,将该点的权值赋值为0,代表已经寻找过了这个节点了
*	寻找完最小值(最小权值以后)我们就要重新将的内容进行一个更新,同时将他的边/权值替换为寻找到最小值的那个顶点后的那些边,同时小于他的权值都要更新他的vex值,所以这就是为什么他可以有类似于“回归节点再去寻找”的类似方法,他并不会把所有遍历的节点都给存储进去
*/

void prim(Graph* G, int index) 
{
	int i=0,j=0;
	Edge *edge = initEdeg(G,index);
	int min = 0;

	for(i=0;i<G->vexNum-1;i++)
	{
		min = getMinEdge(edge,G);
		printf("v%c --> v%c, weight = %d\n", edge[min].vex, G -> vexs[min], edge[min].weight);
		edge[min].weight = 0;
		for(j=0;j<G->vexNum;j++)
		{
			if(edge[j].weight > G->arcs[min][j] && edge[j].weight)
			{
				edge[j].weight = G->arcs[min][j];
				edge[j].vex = G->vexs[min];
			}
		}
		
	}
} 

总代码

在这里插入图片描述

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

/**
 * 图顶点之前不通,那么邻接矩阵的值为MAX
 * 如果顶点是自己本身,那么值为0
 */
#define MAX 32767

typedef struct Graph {
    char* vexs;
    int** arcs;
    int vexNum;
    int arcNum;
}Graph;

typedef struct Edge {
    char vex;
    int weight;
}Edge;

/**
 * 当edge.weight = 0时,代表顶点加入到U集合中
 */ 
Edge* initEdeg(Graph* G, int index) 
{
	int i=0;
	Edge *T   =	(Edge*)malloc(sizeof(Edge) * G->vexNum);
	for(i=0;i<G->vexNum;i++)
	{
		T[i].vex = G->vexs[index];
		T[i].weight = G->arcs[index][i];
		//printf("T[i].vex->%c, T[i].weight->%d\r\n", T[i].vex,T[i].weight);

	}
	
	return T;
}

int getMinEdge(Edge* edge, Graph* G)
{
	int min = MAX;
	int i=0;
	int index=0;
	for(i=0;i<G->vexNum;i++)
	{
		if(edge[i].weight && edge[i].weight < min)
		{		
			min = edge[i].weight;
			index = i;
		}
	}
	return index;
}

void prim(Graph* G, int index) 
{
	int i=0,j=0;
	Edge *edge = initEdeg(G,index);
	int min = 0;

	for(i=0;i<G->vexNum-1;i++)
	{
		min = getMinEdge(edge,G);
		
		printf("v%c --> v%c, weight = %d\n", edge[min].vex, G -> vexs[min], edge[min].weight);
		edge[min].weight = 0;
		for(j=0;j<G->vexNum;j++)
		{
			if(edge[j].weight > G->arcs[min][j] && edge[j].weight)
			{
				edge[j].weight = G->arcs[min][j];
				edge[j].vex = G->vexs[min];
			}
		}
		
	}
} 

Graph* initGraph(int vexNum) 
{
	int i = 0;
    Graph* G = (Graph*)malloc(sizeof(Graph));
    G -> vexs = (char*)malloc(sizeof(char) * vexNum);
    G -> arcs = (int**)malloc(sizeof(int*) * vexNum);
    for (i = 0 ; i < vexNum; i++) {
        G -> arcs[i] = (int*)malloc(sizeof(int) * vexNum);
    }
    G -> vexNum = vexNum;
    G -> arcNum = 0;
    return G;
}

void createGraph(Graph* G, char* vexs, int* arcs) 
{
	int i=0,j=0;

    for (i = 0 ; i < G -> vexNum; i++) 
	{
        G -> vexs[i] = vexs[i];
        for (j = 0; j < G -> vexNum; j++) 
		{
            G -> arcs[i][j] = *(arcs + i * G -> vexNum + j);
            if (G -> arcs[i][j] != 0 && G -> arcs[i][j] != MAX)  
                G -> arcNum ++;
        }
    }
    G -> arcNum /= 2;
}

void DFS(Graph* G, int* visited, int index) 
{
	int i=0;
    printf("%c\t", G -> vexs[index]);
    visited[index] = 1;
    for (i = 0; i < G ->vexNum; i++) 
	{
        if (G -> arcs[index][i] > 0 && G -> arcs[index][i] != MAX && !visited[i]) 
		{
            DFS(G, visited, i);
        }
    }
}

int main() 
{
	int i=0;
	int arcs[6][6] = {
        0, 6, 1, 5, MAX, MAX,
        6, 0, 5, MAX, 3, MAX,
        1, 5, 0, 5, 6, 4,
        5, MAX, 5, 0, MAX, 2,
        MAX, 3, 6, MAX, 0, 6,
        MAX, MAX, 4, 2, 6, 0
    };
	Graph* G = initGraph(6);
	int* visited = (int*)malloc(sizeof(int) * G -> vexNum);
    
    
    for (i = 0; i < G -> vexNum; i++)
        visited[i] = 0;
    
    createGraph(G, "123456", (int*)arcs);
    DFS(G, visited, 0);
    printf("\n");
    prim(G, 0);
    return 0;
}

最后树得出来的样式图
在这里插入图片描述

往期回顾

1.【第一章】《线性表与顺序表》
2.【第一章】《单链表》
3.【第一章】《单链表的介绍》
4.【第一章】《单链表的基本操作》
5.【第一章】《单链表循环》
6.【第一章】《双链表》
7.【第一章】《双链表循环》
8.【第二章】《栈》
9.【第二章】《队》
10.【第二章】《字符串暴力匹配》
11.【第二章】《字符串kmp匹配》
12.【第三章】《树的基础概念》
13.【第三章】《二叉树的存储结构》
14.【第三章】《二叉树链式结构及实现1》
15.【第三章】《二叉树链式结构及实现2》
16.【第三章】《二叉树链式结构及实现3》
17.【第三章】《二叉树链式结构及实现4》
18.【第三章】《二叉树链式结构及实现5》
19.【第三章】《中序线索二叉树理论部分》
20.【第三章】《中序线索二叉树代码初始化及创树》
21.【第三章】《中序线索二叉树线索化及总代码》
22【第三章】《先序线索二叉树理论及线索化》
23【第三章】《先序线索二叉树查找及总代码》
24【第三章】《后续线索二叉树线索化理论》
25【第三章】《后续线索二叉树总代码部分》
26【第三章】《二叉排序树基础了解》
27【第三章】《二叉排序树代码部分》
28【第三章】《二叉排序树代码部分》
29【第三章】《平衡二叉树基础概念》
30【第三章】《平衡二叉树的平衡因子》
31【第三章】《平衡二叉树的旋转基础详解》
32【第三章】《平衡二叉树的旋转类型图文详解》
33【第三章】《平衡二叉树的旋转类型总结及总代码》
34【第三章】《哈夫曼树简单了解》
35【第三章】《哈夫曼树的构造方法》
36【第三章】《哈夫曼编码构造及代码》
37【第四章】《图的定义》
38【第四章】《图的基本概念和术语》
39【第四章】《图的存储结构》
40【第四章】《图的遍历之深度优先遍历》
41【第四章】《广度优先遍历BFS》
42【第四章】《图的遍历总代码》
43【第四章】《最小生成树概念》
44【第四章】《最小生成树的应用举例》
45【第四章】《prim算法(普里姆算法)详解》
46【第四章】《prim算法(普里姆算法)详解2》
47【第四章】《prim算法(普里姆算法)详解3》
48【第四章】《prim算法(普里姆算法)讲解汇总》
49【第四章】《prim算法(普里姆算法)代码讲解》

标签:index,prim,weight,min,int,MAX,edge,算法,从零开始
From: https://blog.csdn.net/qq_62548908/article/details/140615641

相关文章

  • 算法识别(一)--TEA及其魔改
    0x01算法概要TEA(tinyencryptionalgorithm),属于分组算法,每次操作64位数,分成2个4字节无符号整数(unsignedint),密钥128位,为4个4字节无符号整型(unsignedint),delta(unsignedint)一般为0x9e3779b9,进行轮数一般>=32轮.0x02算法实现c实现#include<cstdint>unsigne......
  • 快速学习一个算法,Transformer
    今天给大家介绍一个强大的算法模型,TransformerTransformer模型是由Vaswani等人在2017年提出的一种用于自然语言处理的深度学习模型,特别擅长于处理序列到序列的任务,如机器翻译、文本生成等。今天,我们主要从编码的角度来进行说明。Transformer模型架构Transformer......
  • 【数据结构】排序算法——Lessen1
    Hi~!这里是奋斗的小羊,很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎~~......
  • 2024“钉耙编程”中国大学生算法设计超级联赛(2)1003
    绝对不模拟的简单魔方要相信题目的提示(直接模拟的代码长达300行),由于魔方的特性,不论如何转动脚上的色块颜色不会变动,只要枚举8个角块看看是否一致即可,枚举角块时需确定访问角块颜色的顺序,例如以3号为顶,后左上访问顺序为123即坐标为\((3,4)->(4,3)-(4,4)\),那么可以通过此角......
  • 素性测试算法
    素数拥有许多特殊的性质,这让它在计算机科学中被广泛应用。例如,著名的RSA加密算法基于两个质数的乘积的难分解性;同时,其正确性基于质数的费马小定理和一些推论。因此,快速判定一个大整数是否是质数是重要的课题。试除法由于质数\(p\)只有\(1\)和\(p\)两个正因数,对于正整......
  • 「代码随想录算法训练营」第十八天 | 二叉树 part8
    669.修剪二叉搜索树题目链接:https://leetcode.cn/problems/trim-a-binary-search-tree/题目难度:中等文章讲解:https://programmercarl.com/0669.修剪二叉搜索树.html视频讲解:https://www.bilibili.com/video/BV17P41177ud?share_source=copy_web题目状态:没有思路,看题解过......
  • [UE 虚幻引擎] DTHmacSha 蓝图HMACSHA加密算法插件说明
    本插件可以在虚幻引擎中使用蓝图对字符串和文件进行HMACSHA加密。1.节点说明HMACSHA一共有5种加密方式,分辨是HMACSHA-1,HMACSHA-224,HMACSHA-256,HMACSHA-384,HMACSHA-512。本插件对每种加密方式提供3个节点,一般节点返回通用值,如7c4a8d09ca3762af61e59520943dc26494f8941b;t......
  • 【视频】Python遗传算法GA优化SVR、ANFIS预测证券指数ISE数据-CSDN博客
    全文链接:https://tecdat.cn/?p=37060本文旨在通过应用多种机器学习技术,对交易所的历史数据进行深入分析和预测。我们帮助客户使用了遗传算法GA优化的支持向量回归(SVR)、自适应神经模糊推理系统(ANFIS)等方法,对数据进行了特征选择、数据预处理、模型训练与评估。实验结果表明,这些方法......
  • 计算机体系结构|| Tomasulo算法(5)
    实验5Tomasulo算法5.1实验目的(1)加深对指令集并行性及开发的理解。(2)加深对Tomasulo算法的理解。.(3)掌握Tomulo算法在指令流出、执行、写结果各阶段对浮点操作指令以及load和store指令进行什么处理。(4)掌握采用了Tomasulo算法的浮点处理部件的结构。(5)掌握保留站的结构。(6)给......
  • 算法——滑动窗口(day7)
    904.水果成篮 904.水果成篮-力扣(LeetCode) 题目解析:根据题意我们可以看出给了我们两个篮子说明我们在开始采摘到结束的过程中只能有两种水果的种类,又要求让我们返回收集水果的最大数目,这不难让我们联想到题目的另一层意思:求最长连续子数组,条件为不超过两种水果种类。......