数据结构与算法(java):图的加权实现

加权图

简介

无论时加权无向图还是加权有向图都是再无向图和有向图的基础上再定义边的大小而已,这个边的大小也叫做权重,不过这个权重的含义会根据问题的描述而不同,例如两个地点间的距离用权表示就路径长度,或者两个信号塔之间通信所花的时间也可用权重来表示,表示时长。

加权的作用

举个生活中常见的例子,例如从一个地方打车另一个地方,可以有多条路径做选择,毕竟条条大路通罗马嘛,但如果需要以最快的速度到达目的地呢,那么你需要找到花费时间最少的那条路径,怎么找呢?这就可以发挥加权的作用了,可以在每条路径上标记所花时间,通过加法运算后作比较,找出花时间做少的那条路径,这也就是最短路径问题。

加权实现

顶点节点

/**
 * vertexData 表头结点中的数据域
 * firstEdge 表头结点中的指针域,指向边表第一个结点
 */
public class VertexNode {
    String vertexData;
    EdgeNode firstEdge;

    public VertexNode(){

    }
}

边结点

/**
 * EdgeNode 边结点数据域,存储数组下标
 * weight 存储权值
 * nextEdge 边结点指针域,指向下一个边结点
 */
public class EdgeNode {
    int EdgeData;
    int weight;
    EdgeNode nextEdge;

    public EdgeNode(){

    }
}
//加权无向图/有向图的实现
import java.util.Scanner;

public class Graph {
    // 定义一个顶点类型数组,存储图的各个顶点
    private VertexNode[] headVertex;
    // 顶点个数
    private int numOfVertexs;
    // 边的个数
    private int numOfEdges;

    //构造函数,初始化顶点
    public Graph(){
        System.out.println("请输入顶点个数:");
        Scanner sc = new Scanner(System.in);
        this.numOfVertexs = sc.nextInt();
        System.out.println("请依次输入各个顶点:");
        //声明顶点数组
        headVertex = new VertexNode[numOfVertexs];
        for (int i = 0; i < numOfVertexs; i++) {
            headVertex[i] = new VertexNode();
            headVertex[i].vertexData = sc.next();
            headVertex[i].firstEdge = null;
        }
    }

    //添加边,构建图
    public void createGraph(){
        Scanner sc = new Scanner(System.in);
        System.out.println("请问你将输入几条边");
        this.numOfEdges = sc.nextInt();
        for (int i = 0; i < numOfEdges; i++) {
            System.out.println("第" + (i+1) + "条边和权");
            String v1 = sc.next();
            String v2 = sc.next();
            int w = sc.nextInt();
            //添加边
            addEdge(v1, v2, w);
        }
    }

    //添加边
    public void addEdge(String v1, String v2, int weight){
        int i1 = getIndexByString(v1);
        int i2 = getIndexByString(v2);
        EdgeNode edgeNode1 = new EdgeNode();
        edgeNode1.EdgeData = i2;
        if(headVertex[i1].firstEdge == null){
            headVertex[i1].firstEdge = edgeNode1;
            edgeNode1.weight = weight;
        }else{
            EdgeNode eNode1 = headVertex[i1].firstEdge;
            while(eNode1.nextEdge != null){
                eNode1 = eNode1.nextEdge;
            }
            eNode1.nextEdge = edgeNode1;
            eNode1.nextEdge.weight = weight;
        }
    //加上下面的就是加权无向图
//        EdgeNode edgeNode2 = new EdgeNode();
//        edgeNode2.EdgeData = i1;
//        if(headVertex[i2].firstEdge == null){
//            headVertex[i2].firstEdge = edgeNode2;
//            edgeNode2.weight = weight;
//        }else{
//            EdgeNode eNode2 = headVertex[i2].firstEdge;
//            while(eNode2.nextEdge != null){
//                eNode2 = eNode2.nextEdge;
//            }
//            eNode2.nextEdge = edgeNode2;
//            eNode2.nextEdge.weight = weight;
//        }
    }

    //输出邻接表:用顶点值表示边表结点
    public void showGraphWithVertex() {
        System.out.println("该图的邻接表为:");
        for (int i = 0; i < numOfVertexs; i++) {
            System.out.print(headVertex[i].vertexData);
            EdgeNode nextNode = headVertex[i].firstEdge;
            while (nextNode != null) {
                System.out.print("-->" + getNameOfVertexByIndex(nextNode.EdgeData)+":weight="+nextNode.weight);
                nextNode = nextNode.nextEdge;
            }
            System.out.println();
        }
    }

    //通过传进来的字符获取对应顶点的索引
    private int getIndexByString(String v){
        for (int i = 0; i < numOfVertexs; i++) {
            if(v.equals(headVertex[i].vertexData)){
                return i;
            }
        }
        return -1;
    }

    //通过传进来的索引获取顶点名
    private String getNameOfVertexByIndex(int index) {
        return headVertex[index].vertexData;
    }
}

测试:

public class GraphTest {
    public static void main(String[] args) {
        Graph graph = new Graph();
        graph.createGraph();
        graph.showGraphWithVertex();
    }
}

结果:

请输入顶点个数:
4
请依次输入各个顶点:
A B C D
请问你将输入几条边
41条边和权
A B 42条边和权
A C 53条边和权
A D 54条边和权
B D 6
该图的邻接表为:
A-->B:weight=4-->C:weight=5-->D:weight=5
B-->D:weight=6
C
D
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值