前言
Bellman-Ford算法的隊列優化
int[] dis = new int[6];
for (int i = 1; i <= 5; i++) {
if (i == 1){
dis[i] = 0;
}else {
dis[i] = 999999;
}
}
Queue<Integer> que = new LinkedList<>();//記錄最短路徑有過變化的點
que.add(1);//先增加一個源點,算法需要從源點開始
//初始化路徑圖
int[] u = new int[8];//邊的起點
int[] v = new int[8];//邊的終點
int[] w = new int[8];//邊的權值
u[1] = 1; v[1] = 2; w[1] = 2;//各條邊的初始化
u[2] = 1; v[2] = 5; w[2] = 10;
u[3] = 2; v[3] = 3; w[3] = 3;
u[4] = 2; v[4] = 5; w[4] = 7;
u[5] = 3; v[5] = 4; w[5] = 4;
u[6] = 4; v[6] = 5; w[6] = 5;
u[7] = 5; v[7] = 3; w[7] = 6;
//我們使用鄰接表來完成圖的記錄
int[] first = new int[8];
int[] next = new int[8];
for (int i = 1; i <= 7; i++) {
first[i] = -1;
}
for (int i = 1; i <= 7; i++) {
next[i] = first[u[i]];
first[u[i]] = i;
}
這裏不多說,u,v,w跟以前一樣記錄了一條邊的完整信息,u記錄的是邊的起點,v記錄的是邊的終點,w記錄的是邊的權值。然後我們初始化了兩個數組first和next,這是因爲該算法中用到了遍歷一個頂點的所有出邊。所以我們使用了鄰接表來存儲邊的信息,能優化一下算法的執行時間。 while (!que.isEmpty()){
//如果隊列不是空的
//拿到隊列中的第一個點
Integer remove = que.remove();
//遍歷所有的頂點remove的出邊
int k = first[remove];
while (k != -1){
if (dis[v[k]] > dis[u[k]] + w[k]){
//鬆弛成功
dis[v[k]] = dis[u[k]] + w[k];
if (!que.contains(v[k])){
que.add(v[k]);
}
}
k = next[k];
}
}
//算法鬆弛完畢,打印結果
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("Bellman-Ford的隊列優化結果-dis = {");
for (int i = 1; i <=5 ; i++) {
if (i == 5){
stringBuilder.append(dis[i]+"}");
}else {
stringBuilder.append(dis[i]+",");
}
}
Log.e("hero","--"+stringBuilder.toString());
執行結果