类定义如下
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;
}
测试数据
参考的代码