【数据结构与算法】第十七、十八章:加权无向图、最小生成树(切分定理、贪心算法、Prim算法、kruskal算法)

17、加权无向图

加权无向图是一种为每条边关联一个权重值或是成本的图模型。

这种图能够自然地表示许多应用。

在一副航空图中,边表示航线,权值则可以表示距离或是费用。

在一副电路图中,边表示导线,权值则可能表示导线的长度即成本,或是信号通过这条线所需的时间。

此时很容易就能想到,最小成本的问题,例如,从西安飞纽约,怎样飞才能使时间成本最低或者是金钱成本最低?

在下图中,从顶点0到顶点4有三条路径,分别为0-2-3-4,0-2-4,0-5-3-4,通过哪条路径到达4顶点最好呢?

此时就要考虑,那条路径的成本最低

在这里插入图片描述

17.1、边的表示

加权无向图中的边不能简单的使用v-w两个顶点表示了,而必须要给边 关联一个权重值,因此可以使用 对象 来描述一条边

在这里插入图片描述

17.2、加权无向图的实现

  • API

在这里插入图片描述

  • 代码
package chapter17;

import chapter03.Queue;

/**
 * @author 土味儿
 * Date 2021/9/16
 * @version 1.0
 * 加权无向图
 */
public class EdgeWeightedGraph {
   
    /**
     * 顶点数量
     */
    private final int vNum;
    /**
     * 边数量
     */
    private int eNum;
    /**
     * 邻接表
     */
    private Queue<Edge>[] adj;

    /**
     * 构造器
     * @param vNum
     */
    public EdgeWeightedGraph(int vNum) {
   
        // 初始化顶点数量
        this.vNum = vNum;
        // 初始化边数量
        this.eNum = 0;
        // 初始化邻接表
        this.adj = new Queue[vNum];
        // 初始化邻接表中的空队列
        for (int i = 0; i < vNum; i++) {
   
            this.adj[i] = new Queue<Edge>();
        }
    }

    /**
     * 得到顶点数量
     * @return
     */
    public int getVNum(){
   
        return vNum;
    }

    /**
     * 得到边数量
     * @return
     */
    public int geteNum(){
   
        return eNum;
    }

    /**
     * 添加一条边v-w
     * @param e
     */
    public void addEdge(Edge e){
   
        // 因为是无向图,让边e同时出现在e的两个顶点的邻接表中
        int v = e.either();
        int w = e.other(v);
        this.adj[v].enQueue(e);
        this.adj[w].enQueue(e);

        // 边数量加1
        eNum++;
    }

    /**
     * 获取顶点v的所有相邻顶点
     * @param v
     * @return
     */
    public Queue<Edge> adj(int v){
   
        return this.adj[v];
    }

    /**
     * 获取加权无向图中的所有边
     * @return
     */
    public Queue<Edge> edges(){
   
        // 创建一个队列对象,存储所有的边
        Queue<Edge> allEdges = new Queue<>();

        // 遍历图中的每一个顶点,找到每个顶点的邻接表,邻接表中存储了该顶点关联的每一条边
        for(int v=0;v<vNum;v++){
   
            // 遍历顶点v的邻接表,找到每一条和v关联的边
            for (Edge e : adj(v)) {
   
                // 每条边的两个顶点,一大一小,判断大小再添加,可以避免重复
                if(e.other(v) < v){
   
                    allEdges.enQueue(e);
                }
            }
        }

        return allEdges;
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

土味儿~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值