小编的话:
搜索了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