27

本文深入讲解了图遍历的应用案例,包括求从顶点到另一顶点的简单路径及最短路径的方法。此外,还详细介绍了两种构造最小生成树的经典算法——普里姆算法和克鲁斯卡尔算法,并对比了它们的适用场景和时间复杂度。

严蔚敏视频 笔记27

遍历应用举例

1.求一条从顶点i到顶点s的简单路径
void DFSearch(int v,int s,char *PATH) {
    visited[v]=TRUE; //
访问第v个结点
    Append(PATH,getVertex(v));
    for(w=FirstAdjVex(v);w!=0&&!found;w=NextAdjVex(v)) {
        if(w==s) {found=TRUE; Append(PATH,w);}
        else if(!visited[w]) DFSearch(w,LP);
    }
    if(!found) Delete(PATH);
}

2.求两个顶点之间的一条路径长度最短的路径
双链结点:nextpriou
修改入队列操作,插入新的队尾结点时令其priou域的指针指向刚刚出队列的结点

修改出队列操作,出队列时仅移动队头指针而不将队头结点从链表中删除

typedef DuLinkList QueuePtr;

void InitQueue(LinkQueue& Q) {
    Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));
    Q.front->next=Q.rear->next=NULL;
}

void EnQueue(LinkQueue& Q,QElemType e) {
    p=(QueuePtr)malloc(sizeof(QNode));
    p->data=e; p->next=NULL;
    p->priou=Q.front;
    Q.rear->next=p;
    Q.rear=p;
}

void DeQueue(LinkQueue& Q,QElemType &e) {
    Q.front=Q.front->next;
    e=Q.front->data;
}

7.4 最小生成树
构造网的一棵最小生成树:在e条带权的边中选取n-1条(不构成回路),使权值之和最小

算法一:(普里姆算法
取图中任意一个顶点v作为生成树的根,之后若要往生成树上添加顶点w,则在顶点v和顶点w之间必定存在一条边,并且该边的权值在所有连通顶点vw之间的边中取值最小
假设n个顶点分成两个集合:U(包含已落在生成树上的顶点)和V-U(尚未落在生成树上的顶点),则在所有连通U中顶点和V-U中顶点的边中选取权值最小的边

void MiniSpanTree_PRIM(MGraph G,VertexType u) {
    //
记录从顶点集UV-U的代价最小的边的辅助数组:

    struct {
        VertexType adjvex;
        VRType lowcost;
    } closedge[MAX_VERTEX_NUM];

    k=LocateVex(G,u);
    for(j=0;j<G.vexnum;++j) //
辅助数组初始化

        if(j!=k) closedge[j]={u,G.arcs[k][j].adj};
    closedge[k].lowcost=0; //
初始U={u}
    for(i=0;i<G.vexnum;++i) { //
在其余顶点中选择

        k=minimun(closedge); //
求出T的下一个结点(k)
        printf(closedge[k].adjvex,G.vexs[k]);
        closedge[k].lowcost=0; //
k顶点并入U

        for(j=0;j<G.vexnum;++j)
            if(G.arcs[k][j].adj<closedge[j].lowcost)
                colosedge[j]={G.vexs[k],G.arcs[k][j].adj};
    }
}

算法二:(克鲁斯卡尔算法
先构造一个只含n个顶点的子图SG,然后从权值最小的边开始,若它的添加不使SG中产生回路,则在SG上加上这条边,如此重复,直至加上n-1条边为止

算法:
构造非连通图ST={V,{}}
k=i=0;
while(k<n-1) {
    ++i;
   
从边集E中选取第i条权值最小的边
(u,v);
   
(u,v)加入ST后不使ST中产生回路,

       
则 输出边(u,v); k++;
}

普里姆算法的时间复杂度为O(n^2),适合于稠密图
克鲁斯卡尔算法需对e条边按权值进行排序,时间复杂度为O(eloge),适合于稀疏图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值