Prim 普利姆算法-Priority Queue 方法

博客介绍了普利姆算法,提及无向网的最小生成树是图的子集,边数比顶点数少1,边权值和最小且无环。还介绍了Lazy Prim算法,其需用优先队列,以边权值为主元素建最小堆,并给出主要代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

普利姆算法

  1. 最小生成树,Minimum Spanning Tree
    无向网的最小生成树是图的一个子集,在这个子集中,边的数量比顶点数量少1,所有顶点被这些边连接在一起,而且这些边的权值和为最小。值得一提的是,由于最终的结果为树,所以子集中不含有环(cycle).
  2. Lazy Prim 算法
    Lazy Prim算法需要使用优先队列(Priority Queue),队列中的元素为生成边,定义生成边的结构体如下:
typedef struct edge
{
    int from; //start vertex
    int to;   //end vertex
    VRType cost; //weight of cost
}edge;

以边中的权值为Priority Queue的主元素,建立最小堆。

主要代码如下:

typedef edge priority_queue_element;
void mst_prim_lazy(MGraph G, Heap H, int s, edge *mst_edges, int *mst_cost, int (*pf)(priority_queue_element e1, priority_queue_element e2))
{
    int                    i;
    int                    edge_count;
    int                    node_index;
    priority_queue_element arc;

    for(i=0;i<G.vexnum;i++)
    {
        visited[i]=0;
    }
    *mst_cost=0;
    edge_count=0;
    add_edges(G,s,H,pf);

    while(H->size>0 && edge_count!=(G.vexnum-1))
    {
        arc=heap_extract_min(H,pf);
        node_index = arc.to;

        if (!visited[node_index])
        {
            mst_edges[edge_count++]=arc;
            *mst_cost+=arc.cost;
            add_edges(G,node_index,H,pf);
        }
    }

    //need to check if there is MST in the graph
    return;
}

void add_edges(MGraph G,int node_index, Heap H, int (*pf)(priority_queue_element e1, priority_queue_element e2))
{
    int v;
    int w;
    priority_queue_element arc;
    visited[node_index]=1;
    v=node_index;

    for (w = FirstAdjVex(G, G.vexs[v]); w >= 0; w = NextAdjVex(G, G.vexs[v], G.vexs[w]))
    {
        if(!visited[w])
        {
            arc.from=v;
            arc.to=w;
            arc.cost=G.arcs[v][w].adj;
            min_heap_insert(H,arc,pf);
        }
    }
}

int less_than(priority_queue_element e1, priority_queue_element e2)
{
    return (e1.cost<e2.cost);
}

Main 函数如下:

int main(void)
{
    Heap H;
    MGraph G;
    FILE *fp;
    int i;
    int mst_cost=0;
    int s=0;
   

    fp=fopen("UDN.txt","r");
    CreateGraph(&G,fp);
    edge mst_edges[G.vexnum-1];
    init_min_heap(&H, G.arcnum);

    mst_prim_lazy(G,H,s,mst_edges,&mst_cost,less_than);
 
    for(i=0;i<G.vexnum-1;i++)
    {
        printf("-%c-%c-%d-\n", G.vexs[mst_edges[i].from], G.vexs[mst_edges[i].to], mst_edges[i].cost);
    }
    fclose(fp);
    PressEnter;

    return EXIT_SUCCESS;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值