数据结构:Prim算法--最小生成树(邻接链表)

小编的话:

        搜索了CSDN之后,发现几乎没有邻接链表版本的Prim算法实现最小生成树,小编也是使用了几乎6个小时的时间实现它(说来惭愧哈,我很菜.....)

        邻接链表储存图的结构:什么是邻接链表?参考这篇文章用邻接表存储图_chengqiuming的博客-CSDN博客_邻接表存储图

头文件hpp:

#pragma once
#include<iostream>
struct ArcNode { //边结点
	int adjvex;
	ArcNode* nextarc;
	int info;//弧自带的信息
	ArcNode(int adj, int w)
	{
		adjvex = adj; info = w;
		nextarc = NULL;
	}
	void output()
	{
		printf("→(adj=%d,w=%d)", adjvex, info);
	}
};
//顶点结点
struct VexNode
{
	char data;//顶点自带的信息
	ArcNode* firstarc;
	VexNode()
	{
		firstarc = NULL;
	}
	~VexNode()
	{
		//TODO:析构函数释放链表
		delete[]firstarc;
	}
	void output()
	{
		printf("顶点%c", data);
		ArcNode* p = firstarc;
		while (p)
		{
			p->output();
			p = p->nextarc;

		}
		printf("\n");
	}
	void addArc(int adj, int w) {
		//向顶点添加弧
		ArcNode* p = new ArcNode(adj, w);
		p->nextarc = firstarc;
		firstarc = p;
	}
};

struct ALGraph {  // 邻接表方式储存的图

	VexNode* vertices;
	int vexnum; // 顶点数量
	int kind; // 图的种类,0-无向图,1-有向图
	ALGraph(const char* names, int k = 1) {
		//传入一个字符串,根据其中的字符为每一个结点命名
		kind = k;
		vexnum = strlen(names);
		vertices = new VexNode[vexnum];
		for (int i = 0; i < vexnum; i++)
			vertices[i].data = names[i];
	}
	~ALGraph() {
		//析构函数,释放结点表
		delete[]vertices;
	}
	void output() {
		//输出图
		for (int i = 0; i < vexnum; i++)
			vertices[i].output();
	}
	void addArc(int tail, int head, int w = 0)
	{    //向图添加弧 
		vertices[tail].addArc(head, w);
		if (kind == 0)//如果是无向图
			vertices[head].addArc(tail, w);
	}
};

主文件:

#include"图的邻接链表封装.h"
#define MAX_VERTEX_NUM 8
void prim(ALGraph& G)
{
	char adjvex[MAX_VERTEX_NUM];  // 存放起始顶点
	int lowcost[MAX_VERTEX_NUM-2];  // 存放weight
	int U1[MAX_VERTEX_NUM];
	bool U[MAX_VERTEX_NUM];  // 已选顶点集合
	memset(U, 0,sizeof(U)); //对U数组初始化8个false
	memset(U1, 0, sizeof(U1));
	memset(lowcost, 0, sizeof(lowcost));
	memset(adjvex, '0', sizeof(adjvex));
	//实现Prim
	adjvex[0] = '0';
	U1[0] = 0;
	U[0] = true;
	//把跟1顶点邻接的信息存进来
	printf("Prim 选择的边:\n");
	for (int i = 0; i < G.vexnum-1; i++) {
		
		int q;
		q = U1[i];  // 第一个结点是0
		ArcNode* p = G.vertices[q].firstarc; 
		while (p) {
			adjvex[p->adjvex] = G.vertices[q].data;
			lowcost[p->adjvex] = p->info;
			p = p->nextarc;//指针移动
		}
		int min = 100; int k = 0;
		for (int j = 1; j < G.vexnum; j++) {
			if (lowcost[j] != 0 && lowcost[j] < min&& U[j]!=true)
			{
				min = lowcost[j];
				k = j;//记录lowcost最小的下标
				
			}
			
		}
		U[k] = true;
		lowcost[k] = 0; //被选中的lowcost = 0
		
		U1[i + 1] = k;
		printf("v%c - v%c: %d\n",G.vertices[k].data, adjvex[k], min);
		delete[]p;
	}
}

int main() {
	ALGraph G("123456", 0);
	
		
	G.addArc(0, 1, 6); G.addArc(0, 2, 1); G.addArc(0, 3, 5);
	G.addArc(1, 2, 5);G.addArc(1, 4, 3);
	G.addArc(2, 3, 5); G.addArc(2, 4, 6); G.addArc(2, 5, 4);
	G.addArc(3, 5, 2); G.addArc(4, 5, 6);
	prim(G);
	
	return 0;
}

运行结果:

Prim 选择的边:
v3 - v1: 1
v6 - v3: 4
v4 - v6: 2
v2 - v3: 5
v5 - v2: 3

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值