日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java 最小生成树_图的最小生成树(java实现)

發布時間:2025/3/11 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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实现)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。