Java做題要用到的工具

圖的搜索算法:BFS和DFS詳解

參考文章:https://www.jianshu.com/p/2226dbe98e06

DFS(深度優先遍歷)

深度優先搜索是從起始頂點開始,遞歸訪問其所有鄰近節點,比如A節點是其第一個鄰近節點,而C節點又是A的一個鄰近節點,則DFS訪問A節點後再訪問C節點,如果C節點有未訪問的鄰近節點的話將繼續訪問其鄰近節點,否則繼續訪問A的未訪問鄰近節點,當所有從A節點出去的路徑都訪問完之後,繼續遞歸訪問除A以外未被訪問的鄰近節點。
所以上面我們的示意圖的遍歷順序會是A->C->B->D->E->F。

BFS(廣度優先遍歷)

其主要思想是從起始點開始,將其鄰近的所有頂點都加到一個隊列(FIFO)中去,然後標記下這些頂點離起始頂點的距離爲1.最後將起始頂點標記爲已訪問,今後就不會再訪問。然後再從隊列中取出最先進隊的頂點A,也取出其周邊鄰近節點,加入隊列末尾,將這些頂點的距離相對A再加1,最後離開這個頂點A。依次下去,直到隊列爲空爲止。從上面描述的過程我們知道每個頂點被訪問的次數最多一次(已訪問的節點不會再訪問),而對於連通圖來說,每個頂點都會被訪問。加上每個頂點的鄰接鏈表都會被遍歷,因此BFS的時間複雜度是Θ(V+E),其中V是頂點個數,E是邊數,也就是所有鄰接表中的元素個數。
所以我們上圖的遍歷順序將會爲:A->C->D->B->E->F

實現代碼如下:

public class Graph {                   //A, B, C,D, E, F
    static int[][] graph = new int[][]{{0, 0, 1, 1, 0, 0},
            {0, 0, 1, 0, 0, 0},
            {1, 1, 0, 0, 0, 0},
            {0, 0, 1, 0, 1, 0},
            {0, 0, 0, 1, 0, 1},
            {0, 0, 0, 0, 1, 0}};
    int[] help = new int[graph.length];//用來記錄已經遍歷過的元素

    //DFS(深度優先遍歷)同樣適用於有向圖 A->C->B->D->E->F 即 0->2->1->3->4->5
    public void dfsTraversing(int node, int[][] graph) {
        help[node]=1;
        System.out.println(node);
        for (int i = 0; i < graph[node].length; ++i) {
            if (help[i]==0&&i != node&&graph[node][i]==1) {
                dfsTraversing(i, graph);
            }
        }
    }

    //BFS(廣度優先遍歷)同樣適用於有向圖 A->C->D->B->E->F 即0->2->3->1->4->5
    public void bfsTraversing(int[][] graph) {
        int[] queue=new int[graph.length];
        int cnt=1;
        queue[0]=0;//將A作爲起始頂點加入隊列
        help[0]=1;
        System.out.println(0);
        for (int i=0;i<cnt;++i){
            for (int j=0;j<graph[queue[i]].length;++j){
                if (queue[i]!=j&&graph[queue[i]][j]==1&&help[j]==0){
                        help[queue[i]]=1;
                        queue[cnt++]=j;
                        System.out.println(j);
                }
            }
        }
    }
}

DecimalFormat - 格式化數據

參考文章:https://www.jianshu.com/p/c1dec1796062

0佔位符的使用

佔位符比實際數字多
new DecimalFormat("00.00").format(3.14567);//結果:03.15
new DecimalFormat("0.000").format(3.14);//結果:3.140
new DecimalFormat("00.000").format(3.14);//結果:03.140

佔位符比實際數字少
new DecimalFormat("00.00").format(13.14567);//結果:13.15
new DecimalFormat("0.000").format(13.14567);//結果:13.146
new DecimalFormat("0.00").format(13.14567);//結果:13.15

#佔位符的使用

佔位符比實際數字多
new DecimalFormat("##.##").format(3.14567);//結果:3.15
new DecimalFormat("#.###").format(3.14);//結果:3.14
new DecimalFormat("##.###").format(3.14);//結果:3.14

佔位符比實際數字少
new DecimalFormat("#.###").format(13.145678);//結果:13.146
new DecimalFormat("##.##").format(13.14567);//結果:13.15
new DecimalFormat("#.##").format(13.14567);//結果:13.15

DecimalFormat的格式化方式(舍入方式)

DecimalFormat format = new DecimalFormat("#.##");
//指定舍入方式爲:RoundingMode.DOWN,直接捨去格式化以外的部分
format.setRoundingMode(RoundingMode.DOWN);
String formatDown = format.format(13.14567);//結果:13.14
//指定舍入方式爲:RoundingMode.HALF_UP,四捨五入
format.setRoundingMode(RoundingMode.HALF_UP);
String formatHalfUp = format.format(13.14567);//結果:13.15

Dijkstra算法Java實現

import java.util.Scanner;
import java.util.*;

public class Main {

    private static int IMAX = 10000; //不連通狀態
public static int[][] adjMat ={
        {0,1,3,6},
        {1,0,IMAX,6},
        {3,IMAX,0,2},
        {6,6,2,0}
};

    public static void main(String[] args) {

        Dijkstra(adjMat,0,3);
    }

    public static void LoopNode(){
        Node head = new Node();
        Node temp = head;
        for (int i = 0;i<10;i++){
            temp.val = i;
            temp.next = new Node();
            temp = temp.next;
        }
        temp.val = 10;
        temp.next = head;

        Node node1,node2;
        node1 = node2 = head;
        while (true){
            node1 = node1.next;
            node2 = node2.next.next;
            if (node1 == node2)
                break;
        }

        System.out.println("is Loop");

    }

    public static void Dijkstra(int[][] martix,int start,int terminal){
        boolean []isVisted = new boolean[martix.length];
        int []d = new int[martix.length];
        for (int i = 0;i<martix.length;i++){
            isVisted[i] = false; //該點是否被計入,可以理解爲判斷該點是否已經加入集合B
            d[i] = IMAX;//在當前的集合B所能連接的路徑中,從起始點到該點的最短路徑
        }
        isVisted[start] = true;
        d[start] = 0;
        int unVisitNode = martix.length ;
        int index = start;
        while (unVisitNode > 0 && !isVisted[terminal] ){
            int min = IMAX;
            //選出集合A中的點到集合B的路徑最短的點
            for (int i = 0;i<d.length;i++){
                if (min > d[i] && !isVisted[i]){
                    index = i;
                    min = d[i];
                }
            }
            
            
        for (int i = 0;i<martix.length;i++){
                if (d[index] + martix[index][i] < d[i]) //更新當前的最短路徑
                    d[i] = d[index] + martix[index][i];
        }

        unVisitNode -- ;
            isVisted[index] = true;
        }

        System.out.println(d[terminal]);
    }
``
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章