图的最小生成树 C++实现 Prim

类定义如下

class Mgraph {
public:
	Mgraph(int vertex_num, int edge_num) {        //建立一个没有边,只有节点的图
		m_node_nums = vertex_num;
		m_edge_nums = edge_num;
		this->m_node_arr = new Node[this->m_node_nums];//使用的是默认初始化的顶点,没有设定存储的内容
		for (int i = 0; i < this->m_node_nums; i++) {
			for (int j = 0; j < i; j++) {
				this->m_matrix[i][j] = -1;
				this->m_matrix[j][i] = -1;
			}
			this->m_matrix[i][i] = 0;
		}
	}
	void insert_edge(const Edge& e);
	void set_node();
	void reset_visited();
	void BFS_graph();
	void DFS_graph();
	void print_matrix();
	void shortest_path(int v0, int *dist, int* path);//用一个数组来代替visited,同时表示距离
	void min_span_tree_Prim(int i);

private:
	void DFS(int i);

public:
	int m_node_nums;
	int m_edge_nums;
	Node* m_node_arr;
	int m_matrix[MAXSIZE_NUM][MAXSIZE_NUM];//邻接矩阵
};

Prim算法里面,lowcost代表的是生成树这个整体到其他节点的路径,最终目标是把lowcost全部置零,adjvex代表的是从生成树的哪一个顶点上连接的一个顶点。

因为把空路径的权重设置成-1,导致相比设置成一个很大的值,我的Prim算法的逻辑多写了好几个条件,又是一堆一言难尽的代码,,,

void Mgraph::min_span_tree_Prim(int beg) {
	int* adjvex = new int[this->m_node_nums];
	adjvex[beg] = 0;
	int* lowcost = new int[this->m_node_nums];
	lowcost[beg] = 0;
	for (int i = 0; i < this->m_node_nums; i++) {
		lowcost[i] = this->m_matrix[beg][i];
		adjvex[i] = beg;
	}
	for (int i = 0; i < this->m_node_nums; i++) {
		int min = INFINITY;
		int cur = 0;
		if (i == beg) {
			continue;
		}
		for (int j = 0; j < this->m_node_nums; j++) {
			if (lowcost[j] != -1 && lowcost[j] != 0 && lowcost[j] < min) {
				//找到此顶点的最短边,-1 代表无连接,0 代表顶点已经在树里面
				min = lowcost[j];
				cur = j;
			}
		}
		cout << "增加顶点,从" <<adjvex[cur] << "连到"  << cur << endl;
		lowcost[cur] = 0;//置零表示把这个节点纳入生成树
		 
		//下面的程序用来更新lowcost,对于一个新的顶点cur,会怎么影响这两个数组
		for (int j = 0; j < this->m_node_nums; j++) {
			if (this->m_matrix[cur][j] == -1) {
				continue;
			}
			if (lowcost[j] != 0) {
				//如果新加入的点到没加入的点的权值 < 原本的点到这些点的权值
				if (lowcost[j] == -1) {
					lowcost[j] = this->m_matrix[cur][j];
					adjvex[j] = cur;
				}
				else if(lowcost[j] > this->m_matrix[cur][j]) {
					lowcost[j] =  this->m_matrix[cur][j];
					adjvex[j] = cur;
				}
			}
		}

	}
    delete[] adjvex;
	delete[] lowcost;

}

测试数据

 参考的代码

来自知乎的一篇文章

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值