一种用于求解最小生成树问题的贪心算法,该算法的基本思想是按照边的权重从小到大排序,然后依次选择边,并加入生成树中,同时确保不会形成环路,直到生成树包含图中所有的顶点为止。
具体步骤:
4.终止条件:当生成树中包含图中的 V-1 条边(其中 V 是图中的顶点数)时,算法终止。此时,生成树即为最小生成树。
一种用于求解最小生成树问题的贪心算法,该算法从一个初始顶点开始,逐步扩展生成树,每次选择权重最小且连接生成树外部顶点的边,直到生成树包含图中所有的顶点为止。
具体步骤:
3.终止条件:当生成树中包含图中的 V 个顶点时,算法终止。此时,生成树即为最小生成树。
(1)输入:
一个包含所有边及其权重的图和图中的顶点数。
(2)流程:
读取图中的所有边,并存储它们的权重,使用一种数据结构来存储这些边,以便后续排序。
根据边的权重对所有边进行排序,确保权重最小的边排在前面。
创建一个空的生成树结构,用于存储最终的最小生成树,并使用并查集数据结构来跟踪图中的连通分量。
遍历排序后的边列表,对于每条边,检查其两个端点是否属于同一个连通分量。如果不属于同一个连通分量,则将该边添加到生成树中,并合并这两个连通分量。反之则跳过该边。
跟踪添加到生成树中的边数。当边数达到 V-1(其中 V 是图中的顶点数)时,生成树构建完成。
输出生成树中的边及其权重。
(3)输出:
一个包含 V-1 条边的最小生成树,这些边连接了图中的所有顶点,并且总权重最小。
(1)
输入:
一个包含所有顶点及其相邻顶点和边权重的图以及图中的顶点数。
(2)流程:
选择一个初始顶点,将其标记为已访问,并将其加入生成树。创建一个优先队列(最小堆),用于存储所有连接生成树外部顶点的边及其权重。初始化一个数组或集合来跟踪哪些顶点已经被访问过。
当生成树中的顶点数小于图中的总顶点数时,执行以下步骤:
从优先队列中取出权重最小的边及其连接的外部顶点。将该边及其连接的外部顶点加入生成树,并标记该顶点为已访问。更新优先队列,将新加入的顶点所有连接外部顶点的边及其权重加入队列。
跟踪添加到生成树中的顶点数,当顶点数达到图中的总顶点数时,生成树构建完成。
输出生成树中的边及其权重。
(3)输出:
一个包含 V-1 条边的最小生成树,这些边连接了图中的所有顶点,并且总权重最小。
#include
#include
#include
#define MaxInt 32767
#define MVNum 100
void Interrupt(void)
{
while (1)
if (getchar() == '\n')
break;
}
typedef struct
{
char vexs[MVNum];
int arcs[MVNum][MVNum];
int vexnum, arcnum;
}AMGraph;
struct
{
char Head;
char Tail;
int lowcoat;
}Edge[MVNum];
void InitGraph(AMGraph& G)
{
int i, j;
for (i = 0; i < MVNum; i++)
for (j = 0; j < MVNum; j++)
G.arcs[i][j] = MaxInt;
}
void CreateGraph(AMGraph& G)
{
int i;
char a;
printf("请输入顶点数和边数:");
scanf("%d %d", &G.vexnum, &G.arcnum);
Interrupt();
printf("请输入顶点名称(连续输入):");
for (i = 0; i < G.vexnum; i++)
{
scanf("%c", &a);
G.vexs[i] = a;
}
char b, c;
int w, j, k;
for (i = 0; i < G.arcnum; i++)
{
printf("请输入边的两个顶点和权值w:");
scanf("%c %c %d", &b, &c, &w);
Interrupt();
Edge[i].Head = b;
Edge[i].Tail = c;
Edge[i].lowcoat = w;
for (j = 0; j < G.vexnum; j++)
{
if (G.vexs[j] == b)
break;
}
for (k = 0; k < G.vexnum; k++)
{
if (G.vexs[k] == c)
break;
}
G.arcs[j][k] = G.arcs[k][j] = w;
}
}
void InputGraph(AMGraph G)
{
int i, j;
printf("邻接矩阵为:\n ");
for (i = 0; i < G.vexnum; i++)
printf("%c ", G.vexs[i]);
printf("\n");
for (i = 0; i < G.vexnum; i++)
{
printf("%c ", G.vexs[i]);
for (j = 0; j < G.vexnum; j++)
printf("%d ", G.arcs[i][j]);
printf("\n");
}
}
int Vexset[MVNum];
void Sort(AMGraph G)
{
int i, j;
for (i = G.arcnum - 1; i >= 0; i--)
{
for (j = 0; j < i; j++)
{
if (Edge[j].lowcoat > Edge[j + 1].lowcoat)
{
Edge[G.arcnum] = Edge[j];
Edge[j] = Edge[j + 1];
Edge[j + 1] = Edge[G.arcnum];
}
}
}
}
int LocateVex(AMGraph G, char b)
{
int j;
for (j = 0; j < G.vexnum; j++)
{
if (G.vexs[j] == b)
break;
}
return j;
}
void MiniSpanTree_Kruskal(AMGraph G)
{
int i, j;
Sort(G);
for (i = 0; i < G.vexnum; i++)
Vexset[i] = i;
int v1, v2,
vs1, vs2;
for (i = 0; i < G.arcnum; i++)
{
v1 = LocateVex(G, Edge[i].Head);
v2 = LocateVex(G, Edge[i].Tail);
vs1 = Vexset[v1];
vs2 = Vexset[v2];
if (vs1 != vs2)
{
printf("%c->%c ", Edge[i].Head, Edge[i].Tail);
for (j = 0; j < G.vexnum; j++)
if (Vexset[j] == vs2)
Vexset[j] = vs1;
}
}
}
int main()
{
AMGraph G;
InitGraph(G);
CreateGraph(G);
InputGraph(G);
MiniSpanTree_Kruskal(G);
return 0;
}
#define _CRT_SECURE_NO_WARNINGS
#pragma warning (disable:4996)
#include
#include
#include
#define MaxInt 32767
#define MVNum 100
void Interrupt(void)
{
while (1)
if (getchar() == '\n')
break;
}
typedef struct
{
char vexs[MVNum];
int arcs[MVNum][MVNum];
int vexnum, arcnum;
}AMGraph;
void InitGraph(AMGraph& G)
{
int i, j;
for (i = 0; i < MVNum; i++)
for (j = 0; j < MVNum; j++)
G.arcs[i][j] = MaxInt;
}
void CreateGraph(AMGraph& G)
{
int m,
n,
i;
char a;
printf("请输入顶点数和边数:");
scanf("%d %d", &m, &n);
Interrupt();
G.vexnum = m;
G.arcnum = n;
printf("请输入顶点名称(连续输入):");
for (i = 0; i < m; i++)
{
scanf("%c", &a);
G.vexs[i] = a;
}
Interrupt();
char b, c;
int w, j, k;
for (i = 0; i < n; i++)
{
printf("请输入边的两个顶点和权值w:");
scanf("%c %c %d", &b, &c, &w);
Interrupt();
for (j = 0; j < n; j++)
{
if (G.vexs[j] == b)
break;
}
for (k = 0; k < n; k++)
{
if (G.vexs[k] == c)
break;
}
G.arcs[j][k] = G.arcs[k][j] = w;
}
}
void InputGraph(AMGraph G)
{
int i, j;
printf("邻接矩阵为:\n ");
for (i = 0; i < G.vexnum; i++)
printf("%c ", G.vexs[i]);
printf("\n");
for (i = 0; i < G.vexnum; i++)
{
printf("%c ", G.vexs[i]);
for (j = 0; j < G.vexnum; j++)
printf("%d ", G.arcs[i][j]);
printf("\n");
}
}
struct
{
char adjvex;
int lowcost;
}closedge[MVNum];
int Min(AMGraph G)
{
int i,
a,
min = MaxInt;
for (i = 0; i < G.vexnum; i++)
{
if (closedge[i].lowcost == 0)
continue;
if (min > closedge[i].lowcost)
{
min = closedge[i].lowcost;
a = i;
}
}
return a;
}
void MiniSpanTree_Prim(AMGraph G, char u)
{
int i, j,
k;
for (j = 0; j < G.vexnum; j++)
{
if (G.vexs[j] == u)
break;
}
k = j;
for (j = 0; j < G.vexnum; j++)
{
if (j != k)
{
closedge[j].adjvex = u;
closedge[j].lowcost = G.arcs[k][j];
}
}
closedge[k].lowcost = 0;
char u0, v0;
for (i = 0; i < G.vexnum; i++)
{
k = Min(G);
u0 = closedge[k].adjvex;
v0 = G.vexs[k];
printf("%c->%c ", u0, v0);
closedge[k].lowcost = 0;
for (j = 0; j < G.vexnum; j++)
{
if (G.arcs[k][j] < closedge[j].lowcost)
{
closedge[j].adjvex = G.vexs[k];
closedge[j].lowcost = G.arcs[k][j];
}
}
}
}
int main()
{
AMGraph G;
InitGraph(G);
CreateGraph(G);
InputGraph(G);
MiniSpanTree_Prim(G, 0);
return 0;
}
输入一个有向图:5个顶点为abcde,其中a->b,权重为2;a->c,权重3;b->d权重为3;a->e,权重为4;e->d,权重为5,e->c,权重为6,;d->c,权重为4。经过克鲁斯卡尔算法的执行,成功输出相对应的邻接矩阵,并成功输出最小生成树为a->c,b->d,a->e,d->c。
输入一个有向图:4个顶点为abcd,其中a->b,权重为2;a->c,权重2;a->d权重为3;b->d,权重为4;c->d,权重为5。经过prim算法的执行,成功输出相对应的邻接矩阵,并成功输出最小生成树为a->c,a->d,b->d。