java 最小生成树_图的最小生成树(java实现)
1.圖的最小生成樹(貪心算法)
我兩個算法的輸出都是數組表示的,當前的索引值和當前索引對應的數據就是通路,比如parent[2] = 5;即2和5之間有一個通路,第二個可能比較好理解,第一個有點混亂
是什么?
將一個有權圖中的 所有頂點都連接起來,并保證連接的邊的 總權重最小,即最小生成樹,最小生成樹不唯一
為什么?
傳入鄰接矩陣,返回可以生成最小生成樹的數據
我們有兩種方式生成圖的最小生成樹1.普里姆(Prim)算法2.克魯斯卡爾(Kruskal)算法
怎樣做?
下面是普里姆算法的最小生成樹
下面是克魯斯卡爾算法的最小生成樹:
圖的鄰接矩陣表示法(無向圖,上三角矩陣)
int[][] arr = new int[][]{
{-1, 4, 0, 0, 0, 0, 0, 8, 0},
{0, -1, 8, 0, 0, 0, 0, 11, 0},
{0, 0, -1, 7, 0, 4, 0, 0, 2},
{0, 0, 0, -1, 9, 14, 0, 0, 0},
{0, 0, 0, 0, -1, 10, 0, 0, 0},
{0, 0, 0, 0, 0, -1, 2, 0, 0},
{0, 0, 0, 0, 0, 0, -1, 1, 6},
{0, 0, 0, 0, 0, 0, 0, -1, 7},
{0, 0, 0, 0, 0, 0, 0, 0, -1}
};
1.普里姆算法(加點法)
需求:求出最小生成樹的權值
輸入參數:二維數組arr(鄰接矩陣),列表list(存放已經被加入的點),整型sum(存放權值)
輸出參數:整型數組parent
1)先找一個起點,這個起點為任意一點,放入list中2)如果list中不包含全部節點,進入循環1>遍歷list中節點,查找不存在list中的鄰接節點的最小值,記錄下begin和end2>將begin和end放入數組中,較小值節點賦值給較大值所在數組位置
3)返回parent
實現:
importjava.util.ArrayList;importjava.util.Arrays;importjava.util.List;/*** 普里姆(Prim)算法
*
*@authorXiong YuSong
* 2019/3/22 16:02*/
public classPrim {public static voidmain(String[] args) {int[][] arr = new int[][]{
{-1, 4, 0, 0, 0, 0, 0, 8, 0},
{0, -1, 8, 0, 0, 0, 0, 11, 0},
{0, 0, -1, 7, 0, 4, 0, 0, 2},
{0, 0, 0, -1, 9, 14, 0, 0, 0},
{0, 0, 0, 0, -1, 10, 0, 0, 0},
{0, 0, 0, 0, 0, -1, 2, 0, 0},
{0, 0, 0, 0, 0, 0, -1, 1, 6},
{0, 0, 0, 0, 0, 0, 0, -1, 7},
{0, 0, 0, 0, 0, 0, 0, 0, -1}
};
List list = new ArrayList<>();//先將0放置在list中
list.add(0);int begin = 0, end = 0, weight;int[] parent = new int[arr.length];for (int i = 0; i < arr.length; i++) {
parent[i]= -1;
}while (list.size()
weight=Integer.MAX_VALUE;for(Integer row : list) {for (int i = 0; i < arr.length; i++) {if (!list.contains(i)) {if (i >= row + 1) {if (arr[row][i] > 0 && arr[row][i]
begin=row;
end=i;
weight=arr[row][i];
}
}else if (i <= row - 1) {//我這里只用了上三角矩陣,所以這里需要畫蛇添足寫這一部分
if (arr[i][row] > 0 && arr[i][row]
begin=row;
end=i;
weight=arr[i][row];
}
}
}
}
}
list.add(end);
parent[end]=begin;
}
System.out.println(Arrays.toString(parent));
}
}
2.克魯斯卡爾算法(加邊法)
需求:求出最小生成樹的權值
構建類:Edge三元組,根據weight(權值)排序
輸入參數:存放有Edge的列表list,并查集parent
輸出參數:并查集parent(最小生成樹的數組表現形式)
原理:貪心算法的實現,程序中使用了并查集(判斷兩個集合中是否存在相同的數據)這種特殊的數據結構,使用數組實現
1)創建一個三元組,將鄰接矩陣中數據放入三元組中,再放入list中,根據權值進行排序2)創建變量count=0,整型數組parent3)如果list中還存在值,則進行循環1>判斷begin和end是否存在于不同的集合中(判斷是否在同一棵樹中,即判斷當前節點在并查集parent中的根節點是否為同一個)2>如果存在不同的集合中,則將較小值節點賦值給較大值所在數組位置,較小值節點為較大值節點的父節點4)返回parent
實現:
importjava.util.ArrayList;importjava.util.Arrays;importjava.util.Collections;importjava.util.List;/***@authorXiong YuSong
* 2019/3/22 17:04*/
class Edge implements Comparable{//起始點
private intbegin;//終止點
private intend;//權值
private intweight;public Edge(int begin, int end, intweight) {this.begin =begin;this.end =end;this.weight =weight;
}public intgetBegin() {returnbegin;
}public void setBegin(intbegin) {this.begin =begin;
}public intgetEnd() {returnend;
}public void setEnd(intend) {this.end =end;
}public intgetWeight() {returnweight;
}public void setWeight(intweight) {this.weight =weight;
}
@Overridepublic intcompareTo(Edge o) {if (o.weight > this.weight) {return -1;
}else{return 1;
}
}
}public classKruskal {public static voidmain(String[] args) {
//默認以a為根節點的最小生成樹
List list = new ArrayList<>();int[][] arr = new int[][]{
{-1, 4, 0, 0, 0, 0, 0, 8, 0},
{0, -1, 8, 0, 0, 0, 0, 11, 0},
{0, 0, -1, 7, 0, 4, 0, 0, 2},
{0, 0, 0, -1, 9, 14, 0, 0, 0},
{0, 0, 0, 0, -1, 10, 0, 0, 0},
{0, 0, 0, 0, 0, -1, 2, 0, 0},
{0, 0, 0, 0, 0, 0, -1, 1, 6},
{0, 0, 0, 0, 0, 0, 0, -1, 7},
{0, 0, 0, 0, 0, 0, 0, 0, -1}
};for (int i = 0; i < arr.length; i++) {for (int j = i + 1; j < arr.length; j++) {if (arr[i][j] > 0) {
list.add(newEdge(i, j, arr[i][j]));
}
}
}
Collections.sort(list);//數組中每一個節點都只知道他的父節點是什么,-1表示不存在父節點,0位置是根節點
int[] parent = new int[arr.length];for (int i = 1; i < arr.length; i++) {
parent[i]= -1;
}int m = 0, n = 0;for(Edge edge : list) {//尋找這兩個點有沒有相同的父節點
m =find(parent, edge.getBegin());
n=find(parent, edge.getEnd());if (m !=n && parent[edge.getEnd()]>0) {
parent[edge.getEnd()]=edge.getBegin();
}
}
System.out.println(Arrays.toString(parent));
}private static int find(int[] parent, intch) {while (parent[ch] > 0) {
ch=parent[ch];
}returnch;
}
}
總結
以上是生活随笔為你收集整理的java 最小生成树_图的最小生成树(java实现)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java中fis和fos_java中-的
- 下一篇: 杭州招聘计算机专业毕业生,毕业季必看!杭