带权图最小生成树

一、节点

package weightGraph;

public class Vertex {
    public char label;
    public boolean isInTree;  //Tree,该顶点在最小生成树里,反之就不在

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

二、边

package weightGraph;

public class Edge {
    public int startVert;
    public int endVert;
    public int price;

    public Edge(int startVert, int endVert, int price) {
        this.startVert = startVert;
        this.endVert = endVert;
        this.price = price;
    }
}

三、优先级队列

package weightGraph;

public class PriorityQueue {
    private Edge[] edges;  //有序,从大到小
    private final int MAX_SIZE = 20;
    private int size;  //真实保存的边的条数

    public PriorityQueue() {
        edges = new Edge[MAX_SIZE];
        size = 0;
    }

    //向队列中插入新的边
    public void insert(Edge edge) {  //从小到大有序插入
        int i;
        for (i = 0; i < size; i++) {
            if (edge.price >= edges[i].price) {
                break;
            }
        }
        for (int j = size - 1; j >= i; j--) {
            edges[j + 1] = edges[j];
        }
        edges[i] = edge;
        size++;
    }

    //删除并获取队列中的最小的权的边
    public Edge removeMin() {
        return edges[--size];
    }

    //删除指定下标的边
    public void removeN(int n) {
        for (int i = n; i < size; i++) {
            edges[i] = edges[i + 1];
        }
        size--;
    }

    //获取权重最小的边
    public Edge peekMin() {
        return edges[size - 1];
    }

    //判断队列是不是空
    public boolean isEmpty() {
        return size == 0;
    }

    //获取队列中元素的个数
    public int getSize() {
        return size;
    }

    //获取指定下标的边
    public Edge peekN(int n) {
        return edges[n];
    }

}

四、带权图

package weightGraph;

public class WGraph {
    private Vertex[] vertexList;  //保存图中顶点的数组
    private int[][] adjMat;  //邻接矩阵
    private int nVerts;   //图中存在的节点的计数器
    private final int MAX_VERTS = 20;   //初始化一个图中顶点的最大个数
    private PriorityQueue priorityQueue;
    private int nTree;  //已经求解到的最小生成数的顶点的下标
    private int currentVert;
    public final int INF = 1000000;

    public WGraph() {
        vertexList = new Vertex[MAX_VERTS];
        adjMat = new int[MAX_VERTS][MAX_VERTS];
        for (int i = 0; i < MAX_VERTS; i++) {
            for (int j = 0; j < MAX_VERTS; j++) {
                adjMat[i][j] = INF;
            }
        }

        nVerts = 0;
        priorityQueue = new PriorityQueue();
    }

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

    //更新边
    public void addEdge(int start, int end, int price) {
        //注意:要更新两部分
        adjMat[start][end] = price;
        adjMat[end][start] = price;
    }

    //打印指定的顶点的label
    public void displayVertex(int v) {
        System.out.print(vertexList[v].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 price = adjMat[currentVert][i];
                if(price == INF) continue;
                priorityQueue.insert(new Edge(currentVert,i,price));
            }

            if (priorityQueue.getSize() == 0) {
                System.out.println("当前顶点一个临界点也没有");
                return;
            }

            //删除已经在集合中的点之间的边
            for (int i = 0; i < priorityQueue.getSize(); i++) {
                if (vertexList[priorityQueue.peekN(i).startVert].isInTree && vertexList[priorityQueue.peekN(i).endVert].isInTree) {
                    priorityQueue.removeN(i);
                }
            }

            Edge minEdge = priorityQueue.removeMin();
            int startV = minEdge.startVert;
            currentVert = minEdge.endVert;

            //输出找到的边
            System.out.print(vertexList[startV].label);
            System.out.print(vertexList[currentVert].label + "  ");
        }

        //把顶点的inTree还原
        for (int i = 0; i < nVerts; i++) {
            vertexList[i].isInTree = false;
        }
    }
}

五、测试

package weightGraph;

public class WGraphTest {
    public static void main(String[] args) {
        WGraph wGraph = new WGraph();
        wGraph.insert('A');
        wGraph.insert('B');
        wGraph.insert('C');
        wGraph.insert('D');
        wGraph.insert('E');
        wGraph.insert('F');

        wGraph.addEdge(0, 1, 6);
        wGraph.addEdge(0, 3, 4);
        wGraph.addEdge(1, 2, 10);
        wGraph.addEdge(1, 3, 7);
        wGraph.addEdge(1, 4, 7);
        wGraph.addEdge(2, 3, 8);
        wGraph.addEdge(2, 4, 5);
        wGraph.addEdge(2, 5, 6);
        wGraph.addEdge(3, 4, 12);
        wGraph.addEdge(4, 5, 7);

        wGraph.mstw();
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值