Java 带权图-最小生成树

本文介绍了一个使用优先级队列实现的最小生成树算法。通过构建邻接矩阵并利用优先级队列来选择最短边,逐步构建出图的最小生成树。

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

package com.guge.test.graph;

/**
 * 最小生成树
 * Created by Guge on 2017/6/19.
 */
public class GraphW {
    private final int MAX_SIZE=20;
    private final int INFINITY=100000;
    private Vertex[] vertexList;
    private int[][] adjMat;  //邻接矩阵
    private int currentVert;  //当前顶点
    private PriorityQueue thePQ;  //优先级队列
    private int nTree;  //最小生成树数量
    private int nVerts;

    public GraphW(){
        vertexList=new Vertex[MAX_SIZE];
        adjMat=new int[MAX_SIZE][MAX_SIZE];
        for (int i = 0; i < MAX_SIZE; i++) {
            for (int j = 0; j < MAX_SIZE; j++) {
                adjMat[i][j]=INFINITY;
            }
        }
        thePQ=new PriorityQueue();
        nTree=0;
        nVerts=0;
    }

    public void addVert(char vertex){
        vertexList[nVerts++]=new Vertex(vertex);
    }

    public void addEdge(int start,int end,int weight){
        adjMat[start][end]=weight;
        adjMat[end][start]=weight;
    }

    public void displayVertex(int index){
        System.out.print(vertexList[index].label);
    }


    /**
     * 最小生成树
     */
    public void mstw(){
        currentVert=0;


        while (nTree<nVerts-1){
            vertexList[currentVert].isInTree=true;
            nTree++;

            for (int i = 0; i < nVerts; i++) {  //添加邻边到优先级队列
                if(i==currentVert)
                    continue;

                if(vertexList[i].isInTree)
                    continue;

                int distance=adjMat[currentVert][i];
                if(distance==INFINITY)
                    continue;
                putInPQ(i,distance);
            }

            if(thePQ.isEmpty()){
                System.out.println("the graph is not connected");
                return;
            }

            Edge item= thePQ.removeMin();
            int source=item.srcVert;
            int destVert=item.destVert;
            currentVert=destVert;

            System.out.print(vertexList[source].label);
            System.out.print(vertexList[destVert].label);
            System.out.print(" ");
        }

        for (int i = 0; i < nVerts; i++) {
            vertexList[i].isInTree=false;
        }
    }

    /**
     * 插入优先级队列
     * @param newVert
     * @param distance
     */
    public void putInPQ(int newVert,int distance){
        int queueIndex=thePQ.findIndexByDest(newVert); //查找是否有到达当前顶点的边
        if(queueIndex!=-1){
            Edge old=thePQ.peekN(queueIndex);
            if(old.distance>distance){  //如果队列中的边距离大于新插入的边的距离
                thePQ.removeN(queueIndex);  //删除队列中的边
                Edge newEdge=new Edge(currentVert,newVert,distance);
                thePQ.insert(newEdge);
            }
        }else {  //直接插入新边
            Edge newEdge=new Edge(currentVert,newVert,distance);
            thePQ.insert(newEdge);
        }
    }



    /**
     * 边
     */
    class Edge{
        public int srcVert; //起点
        public int destVert; //终点
        public int distance; //距离

        public Edge(int sv,int dv,int dis){
            srcVert=sv;
            destVert=dv;
            distance=dis;
        }
    }

    /**
     * 顶点
     */
    class Vertex{
        public char label;
        public boolean isInTree;

        public Vertex(char label){
            this.label=label;
            isInTree=false;
        }
    }

    /**
     * 优先级队列
     */
    class PriorityQueue{
        private final int SIZE=20;
        private Edge[] queueArr;
        private int size;
        public PriorityQueue(){
            queueArr=new Edge[SIZE];
            size=0;
        }

        public void insert(Edge item){
            int i;
            for (i = 0; i < size; i++) {
                if(item.distance>=queueArr[i].distance)
                    break;
            }

            for (int j = size-1; j >=i ; j--) {
                queueArr[j+1]=queueArr[j];
            }

            queueArr[i]=item;
            size++;
        }

        public Edge removeMin(){
            return queueArr[--size];
        }

        public Edge removeN(int n){
            Edge temp=queueArr[n];
            for (int i = n; i < size - 1; i++) {
                queueArr[i]=queueArr[i+1];
            }
            size--;
            return temp;
        }

        public Edge peek(){
            return queueArr[size-1];
        }

        public int size(){
            return size;
        }

        public boolean isEmpty(){
            return size==0;
        }

        public Edge peekN(int n){
            return queueArr[n];
        }

        /**
         * 通过目的顶点查找当前索引
         * @param dest
         * @return
         */
        public int findIndexByDest(int dest){
            for (int i = 0; i < size; i++)
                if(queueArr[i].destVert==dest)
                    return i;

                return -1;
        }

    }

}
class GraphWApp{
    public static void main(String[] args) {
        GraphW graphW=new GraphW();
        graphW.addVert('A');
        graphW.addVert('B');
        graphW.addVert('C');
        graphW.addVert('D');
        graphW.addVert('E');
        graphW.addVert('F');

        graphW.addEdge(0,1,6); //AB 6
        graphW.addEdge(0,3,4); //AD 4
        graphW.addEdge(1,2,10); //BC 10
        graphW.addEdge(1,3,7); //BD 7
        graphW.addEdge(1,4,7); //BE 7
        graphW.addEdge(2,3,8); //CD 8
        graphW.addEdge(2,4,5); //CE 5
        graphW.addEdge(2,5,6);  //CF 6
        graphW.addEdge(3,4,12);  //DE 12
        graphW.addEdge(4,5,7); //EF 7


        System.out.println("最小生成树");
        graphW.mstw();
        System.out.println();
    }
}




头疼

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值