图的Prim算法

#include <iostream>
#include <vector>
#include <queue>

#define MaxSize 10
#define eletype int 
using namespace std;

bool visited[MaxSize]; //全局数组,记录结点是否已补访问

typedef struct edgenode {  //边表结点
	int adjvex;  //邻接点
	int weight;  //权值
	edgenode *next; //下一条边
};

typedef struct vertexnode { //顶点结点
	eletype data;  //结点数据
	edgenode *fist;  //指向第一条边
}AdjList[MaxSize];

typedef struct AdjListGraph {
	AdjList adjlist;  //邻接表
	int vex;  //顶点数
	int edge; //边数
};


void Init(AdjListGraph &G) {  //初始化为未访问
	for (int i = 0; i < MaxSize; i++) {
		visited[i] = false;
	}
}

int Location(AdjListGraph &G, eletype c) {  //寻找顶点数据的邻接点
	for (int i = 0; i < G.vex; i++) {
		if (G.adjlist[i].data == c) {
			return i;
		}
	}
	return -1;
}

void Create(AdjListGraph &G) {  //创建图
	cout << "请输入该图的顶点数以及边数:" << endl;
	cin >> G.vex >> G.edge;
	cout << "请输入相关顶点:" << endl;
	for (int i = 0; i < G.vex; i++) {
		cin >> G.adjlist[i].data;
		G.adjlist[i].fist = NULL;
	}
	eletype a, b;
	int c;
	int m, n;
	cout << "请输入相关边的顶点以及权值:" << endl;
	for (int i = 0; i < G.edge; i++) {
		cin >> a >> b>>c;
		m = Location(G, a);  //寻找顶点号
		n = Location(G, b);

		if (m != -1 && n != -1) {  //寻找到位置
			edgenode *temp = new edgenode;
			temp->adjvex = n;
			temp->weight = c;
			temp->next = G.adjlist[m].fist;
			G.adjlist[m].fist = temp;
		}
	}
}

void Prim(AdjListGraph &G, int v) { //prim算法求最小生成树
	vector<int> vec;//保存顶点序号
	vec.push_back(v);
	visited[v] = true;
	cout << "Prim算法得到的边如下:" << endl;
	while (vec.size() != G.vex) {  //当没有访问所有的顶点时
		vector<int>::iterator iter;
		int w, Tag1, Tag2, min = 999;
		edgenode *temp = NULL;  //指向为空地址
		for (iter = vec.begin(); iter != vec.end(); iter++) {
			temp = G.adjlist[*iter].fist;
			if (temp != NULL) {
				w = temp->adjvex;
				if (visited[w] == false) {  //没有被访问
					if (min > temp->weight) {
						min = temp->weight;  //更新min以及顶点序号
						Tag1 = *iter;
						Tag2 = w;
					}
				}
				while (temp->next != NULL) {
					temp = temp->next;
					if (visited[temp->adjvex] == false) {  //判断有没有被访问
						if (min > temp->weight) {
							min = temp->weight;  //更新最小值
							Tag1 = *iter;
							Tag2 = temp->adjvex;  //保存下一个顶点号
						}
					}
				}
			}
  			
		}  //寻找到了最小边以及顶点号
		visited[Tag2] = true;  //标记为访问过
		vec.push_back(Tag2);  //添加到已访问队列
		//下面输出每次得到的边
		cout << G.adjlist[Tag1].data << " " << G.adjlist[Tag2].data << endl;
	}
}

int main() {
	AdjListGraph G;
	Init(G);
	Create(G);  //创建图
	Prim(G,0);
	system("pause");
	return 0;
}

/*
6 20
1 2 3 4 5 6
1 2 6
1 4 5
1 3 1
2 3 5
3 4 5
2 5 3
5 6 6
4 6 2
3 6 4
3 5 6
2 1 6
4 1 5
3 1 1
3 2 5
4 3 5
5 2 3
6 5 6
6 4 2
6 3 4
5 3 6

*/


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值