Graph algorithms - minimum spanning tree

Graph algorithms - minimum spanning tree

Find out in a undirected graph a minimum spanning tree (Minimum Spanning Tree) , this problem of a directed graph is meaningful, but more difficult to find them. There is a minimum spanning tree if and only if FIG. G G is connected. The number of edges in the minimum spanning tree for V 1 \left | V \right |-1

Prim's algorithm

At each step, we must put a node as root and add up the side. Algorithm at any one time, we can see a set of vertices have been added to the tree, while the remaining vertices not yet added to the tree in this case, at every stage of the algorithm may be selected by the edge ( u , v ) (U, v) , such that ( u , v ) (U, v) the value of all u in in the trees but v v minimum boundary value is absent in the tree, and to find a new vertex and adds it to this tree.

Code

As used herein, the adjacency matrix.

void Prim(Graph g)
{
    VertexType adjver[VERNUM];
    WeightType lowcost[VERNUM];
    int i, j, k;
    WeightType min;

    // 初始化,一开始生产树中只有开始的顶点
    // 这里开始的顶点的编号为 0
    for (i = 0; i < g->vernum; i++)
    {
        lowcost[i] = g->arc[0][i];
        adjver[i] = 0;
    }

    for (i = 1; i < g->vernum; i++)
    {
        // 在已生成树的顶点中查找权值最小的邻接点的边
        k = 0;
        min = INFINITY;
        for (j = 1; j < g->vernum; j++)
            if (lowcost[j] != 0 && lowcost[j] < min)
            {
                min = lowcost[j];
                k = j;
            }
		
        // 输出新增加的顶点
        printf("(%d, %d)\n", adjver[k] + 1, k + 1);
        lowcost[k] = 0;	// 标记添加到树中的顶点不再使用

        // 更新图中顶点邻接点的权值及顶点
        for (j = 1; j < g->vernum; j++)
            if (lowcost[j] != 0 && g->arc[k][j] < lowcost[j])
            {
                adjver[j] = k;
                lowcost[j] = g->arc[k][j];
            }
    }
}

input Output

Input vernum: 7
Input arcnum: 12
1 2 2
1 3 4
1 4 1
2 4 3
2 5 10
3 4 2
3 6 5
4 5 7
4 6 8
4 7 4
5 7 6
6 7 1
Prim's algorithm minmum spanning tree:
(1, 4)
(1, 2)
(4, 3)
(4, 7)
(7, 6)
(7, 5)
请按任意键继续. . .

Kruskal's algorithm

The second strategy is to continuously greedy selected in accordance with the right minimum edge side, and when the selected edge ring does not occur as it takes to put the given edge.

Code 1

FIG using the adjacency matrix representation.

void Kruskal(Graph G)
{
    int i, vs1, vs2;
    VertexType v1, v2;
    // 辅助数组
    VertexType head;	// 边的始点
    VertexType tail;	// 边的终点
    ArcType lowcost;	// 边的权值
    int Vexset[VerNum];	// 实际上是一个并查集(不相交集)
    
    // 按图中的边的权值大小排序,存储到前三个数组中
   	Sort(Edge);	// 将前3个数组中的元素按权值从小到大排序
    for(i = 0; i < G->vernum; i++)
    {
        // 获取边始点和终点的下标
        v1 = LocateVex(G, head[i]);
        v2 = LocateVex(G, tail[i]);
        // 获取两个顶点所在的连通分量
        vs1 = Vexset[v1];
        vs2 = Vexset[v2];
        if(vs1 != vs2)
        {
            // 将新添加的边打印输出
            printf("(%d, %d)\n", head[i], tail[i]);
            // 合并 vs1 和 vs2 两个分量,将两个集合统一
            for(j = 0; j < G->vernum; j++)
                if(Vexset[j] == vs2)	// 集合编号为 vs2 的都改为 vs1
                    Vexset[j] = vs1;
        }
    }
}

Code from Yan Wei Min "data structure (C language version) (Version 2)" In fact, this code is not explained clearly running behind it, there are castrated introduced two data structures.

Code 2

void Kruskal(Graph G)
{
    int EdgeAccepted;
    DisjSet S;	// 并查集(不相交集)
    PriorityQueue H;	// 优先队列
    Vertex U, V;
    SetType Uset, Vset;	// 并查集根的数据类型
    Edge E;
    
    // 初始化并查集,一开始每个顶点都在一个单独的集合中
    Intialize(S);
    // 构造优先队列(实际上就是对边的权值进行排序)
    ReadGraphIntoHeapArray(G, H);	// 将每条边放到优先队列中(此时未排序)
    BuildHeap(H);	// 对优先队列进行“排序”
    
    // 最小生成树中边的个数是顶点的个数减1
    EdgeAccepted = 0;
    while(EdgeAccepted < NumVertex - 1)
    {
        // 从优先队列取出权值为最小值的边并删除
        // E中有两个点,始点和终点,E = (U, V)
        E = DeleteMin(H);
        // 查找两个顶点所在的集合
        Uset = Find(U, S);
        Vset = Find(V, S);
        if(Uset != Vset)
        {
            // 输出生产的边
            printf("(%d, %d)\n", U, V);
            EdgeAccepted++;
            // 合并两个集合
            SetUnion(S, Uset, Vset);
        }
    }
    
}

Mark Allen Weiss codes from "Data structure and algorithm analysis in C language."

发布了32 篇原创文章 · 获赞 18 · 访问量 3229

Guess you like

Origin blog.csdn.net/u011714517/article/details/104302639