当前位置: 首页 > news >正文

第十六章 常用算法

1.二分查找算法(非递归)

package binarysearchnorecursion;

public class Test {
	public static void main(String[] args) {
		int[]arr= {1,2,3,4,5};
		System.out.println(binarySearch(arr, 5));
	}
	public static int binarySearch(int[]arr,int target) {
		int left=0;
		int right=arr.length-1;
		
		while(left<=right) {
			int mid=(left+right)/2;
			if(arr[mid]==target) {
				return mid;
			}else if(arr[mid]>target) {
				right=mid-1;
			}else {
				left=mid+1;
			}
		}
		return -1;
	}
}

2.分治算法

 

package binarysearchnorecursion;

public class Test {
	public static void main(String[] args) {
		hanoiTower(3, 'a', 'b', 'c');
	}
	public static void hanoiTower(int num,char a,char b,char c) {
		//如果只有一个盘
		if(num==1) {
			System.out.println("第一个盘从"+a+"->"+c);
		}else {
			//如果我们有n>=2情况,我们总是可以将下面看成两个盘1最下面的一个盘 2.上面的所有盘
			//1.先把 最上面的所有盘A-B 移动过程中会使用到c
			hanoiTower(num-1, a, c, b);
			//2.把最下面的盘A->c
			System.out.println("第"+num+"个盘子从"+a+"->"+c);
			//3.把B所有盘从B->C 移动过程中使用到a
			hanoiTower(num-1, b, a, c);
		}
	}
}

3.动态规划算法



public class Test {
    public static void main(String[] args) {
        int[]w= {1,4,3};//物品重量
        int[]val= {1500,3000,2000};//物品价值
        int m=4;//背包一共有多沉
        int n=val.length;//一共多少个物品

        int[][]v=new int[n+1][m+1];//创建一个二维数组表示物品的价值
        int[][]path=new int[n+1][m+1];//表示物品重量
        for(int i=0;i<v.length;i++) {//把第一行设置为0
            v[i][0]=0;
        }
        for(int i=0;i<v[0].length;i++) {//把第一列设置为0
            v[0][i]=0;
        }
        for(int i=1;i<v.length;i++) {//横向遍历
            for(int j=1;j<v[0].length;j++) {//纵向遍历
                if(j<w[i-1]) {//当背包容量小于物品重量时
                    v[i][j]=v[i-1][j];//将此时的值设为上一个物品的同容量的价值
                }else {//背包容量大于等于当前遍历到的物品重量
                    if(v[i-1][j]<val[i-1]+v[i-1][j-w[i-1]]) {//判断上一个阶段的价值和当前物品+上减去当前物品重量剩余重量能拿的最大价值的物品
                        v[i][j]=val[i-1]+v[i-1][j-w[i-1]];//大于直接赋值
                        path[i][j]=1;//表示装了新物品
                    }else {
                        v[i][j]=v[i-1][j];//小于直接用上一个
                    }
                }
            }
        }
        for(int i=0;i<v.length;i++) {//遍历背包
            for(int j=0;j<v[0].length;j++) {
                System.out.print(v[i][j]+" ");
            }
            System.out.println();
        }
        int i=path.length-1;//因为之前为了添加0增加过1
        int j=path[0].length-1;
        while(i>0&&j>0) {
            if(path[i][j]==1) {
                System.out.println("第"+i+"个商品放入背包");
                j-=w[i-1];//背包还剩余容量能放入的最大价值
            }
            i--;//上一个商品
        }
    }
}

4.暴力匹配(字符串匹配问题)

public class Test{
    public static void main(String[] args) {
        String str2="abc你好呀!嘻嘻嘻";
        String str1="埃及地啊你噶,abc你好呀!嘻嘻嘻";
        int i=violenceMatch(str1, str2);
        System.out.println();
    }
    public static int violenceMatch(String str1,String str2) {
        char[]a1=str1.toCharArray();//把`字符串变成字符数组
        char[]a2=str2.toCharArray();
        int s1Len=a1.length;//求出长度
        int s2Len=a2.length;
        int i=0;
        int j=0;
        while(i<s1Len&&j<s2Len) {
            if(a1[i]==a2[j]) {
                i++;
                j++;
            }else {
                i=i-(j-1);//因为i要向前移动一个不能全部减掉
                j=0;
            }
        }
        if(j==s2Len) {//匹配完成,返回str1起始位置
            return i-j;
        }else {
            return -1;//没找到
        }
    }
}

5.KMP算法介绍 (字符串匹配问题)

 

 

 

import java.util.Arrays;

public class Test{
    public static void main(String[] args) {
        String str="AAAAB";//要匹配的字符串
        int []arr=kmpNext(str);
        System.out.println(Arrays.toString(arr));
    }
    public static int[] kmpNext(String dest) {
        int []next=new int[dest.length()];//用next装前缀和后缀长度
        next[0]=0;//1个数的时候匹配值肯定为0
        for(int i=1,j=0;i<dest.length();i++) {//开始遍历
            while(j>0&&dest.charAt(i)!=dest.charAt(j)) {//kmp算法核心 j移到0的位置或者i和j的数相等
                j=next[j-1];//在j在的位置向前移动一个位置
            }
            if(dest.charAt(i)==dest.charAt(j)) {
                j++;
            }
            next[i]=j;//前缀和后缀最大相同长度
        }
        return next;
    }
}

 例子

    public class Test {

    // 计算部分匹配表(前缀表)
    private static int[] computeLPSArray(String pattern) {
        int m = pattern.length();
        int[] lps = new int[m];
        int length = 0;
        int i = 1;
        lps[0] = 0;

        while (i < m) {
            if (pattern.charAt(i) == pattern.charAt(length)) {
                length++;
                lps[i] = length;
                i++;
            } else {
                if (length != 0) {
                    length = lps[length - 1];
                } else {
                    lps[i] = 0;
                    i++;
                }
            }
        }
        return lps;
    }

    // 使用 KMP 算法进行字符串匹配
    public static void KMPSearch(String text, String pattern) {
        int n = text.length();//求出文本字符串长度
        int m = pattern.length();//要匹配的字符串长度
        int[] lps = computeLPSArray(pattern);//将匹配字符串的部分匹配值计算出来
        int i = 0;//便利文本字符串
        int j = 0;//遍历匹配字符串

        while (i < n) {//文本字符串还有值
            if (pattern.charAt(j) == text.charAt(i)) {//如果相等两个字符串都向前推进
                j++;
                i++;
            }

            if (j == m) {//如果j=m代表匹配成功了,结束匹配
                System.out.println("在索引 " + (i - j) + " 处找到匹配");//i-j即开始匹配的位置

            } else if (i < n && pattern.charAt(j) != text.charAt(i)) {//如果i小于n并且遇到了不匹配的字符
                if (j != 0) {//j不等于0的话
                    j = lps[j - 1];//让j等于j-1个前面已经匹配上的值
                } else {//j=0,i++表示没有部分匹配值
                    i++;
                }
            }
        }
    }

    public static void main(String[] args) {
        String text = "ABCABCD";
        String pattern = "ABCD";
        KMPSearch(text, pattern);
    }
}

6.贪心算法

介绍:

  1. 贪心算法是指在对问题进行求解时,在每一步选择中都采取最好或者最优(即最优利)的选择,从而希望能够导致结构是最好或者最优的算法

  2. 贪心算法所得到的结果不一定是最优的结果(有时候会是最优解),但是都是相对近似(接近)最优解的结果

 

 



import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;

public class Test{
    public static void main(String[] args) {
        //创建广播电台,放入到Map broadcasts
        HashMap<String,HashSet<String>> broadcasts=new HashMap<String,HashSet<String>>();
        //将各个电台放入到broadcasts
        HashSet<String> hashSet1=new HashSet<>();//创建广播用来存放可以广播的地区
        hashSet1.add("北京");
        hashSet1.add("上海");
        hashSet1.add("天津");
        HashSet<String> hashSet2=new HashSet<>();
        hashSet2.add("广州");
        hashSet2.add("北京");
        hashSet2.add("深圳");
        HashSet<String> hashSet3=new HashSet<>();
        hashSet3.add("成都");
        hashSet3.add("上海");
        hashSet3.add("杭州");
        HashSet<String> hashSet4=new HashSet<>();
        hashSet4.add("上海");
        hashSet4.add("天津");

        HashSet<String> hashSet5=new HashSet<>();
        hashSet5.add("杭州");
        hashSet5.add("大连");
        broadcasts.put("K1", hashSet1);//将广播和序号联系上
        broadcasts.put("K2", hashSet2);
        broadcasts.put("K3", hashSet3);
        broadcasts.put("K4", hashSet4);
        broadcasts.put("K5", hashSet5);
        //allAreas 存放所有的地区
        HashSet<String> allAreas=new HashSet<String>();
        allAreas.add("北京");
        allAreas.add("上海");
        allAreas.add("天津");
        allAreas.add("广州");
        allAreas.add("深圳");
        allAreas.add("成都");
        allAreas.add("杭州");
        allAreas.add("大连");
        //创建ArrayList ,存放选择的电台集合 selects
        ArrayList<String> selects=new ArrayList<>();
        //定义一个临时的集合,在遍历过程中,存放遍历过程中的电台覆盖的地区和当前还没有覆盖的地区的交集
        HashSet<String> tempSet=new HashSet<String>();
        String maxKey=null;
        //定义给maxKey,保存在一次遍历过程中,能够覆盖最大未覆盖的地区对应的电台的key
        //如果maxKey不为null,则会加入到selects
        while(allAreas.size()!=0) {//当没遍历完所有地区时一直遍历
            maxKey=null;
            for(String key:broadcasts.keySet()) {//遍历广播
                tempSet.clear();
                HashSet<String> areas=broadcasts.get(key);//得到这个广播可以覆盖的地区
                tempSet.addAll(areas);//临时可以覆盖的地区
                tempSet.retainAll(allAreas);//保留tempset里面的地区在allareas存在的地区
                if(tempSet.size()>0&&
                        (maxKey==null||tempSet.size()>broadcasts.get(maxKey).size()))//当tempset>0时并且maxkey=null或者当前遍历到的广播比之前覆盖最多的还多
                {
                    maxKey=key;//将当前电视台放入
                }
            }
            if(maxKey!=null) {//如果不为空,则添加到select
                selects.add(maxKey);
                allAreas.removeAll(broadcasts.get(maxKey));//并移除在area中所有maxkey的地区
            }
        }
        System.out.println("得到的结果是"+selects);
    }
}

7.普里姆算法 Prim

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;

public class Test{
    public static void main(String[] args) {
        char[]data= {'A','B','C','D','E','F','G'};//创建7个结点
        int verxs=data.length;//一共有几个结点
        int[][]weight=new int[][] {//10000表示不是相邻的结点,正常的表示相距的距离
                {10000,5,7,10000,10000,10000,2},
                {5,10000,10000,9,10000,10000,3},
                {7,10000,10000,10000,10000,8,2},
                {10000,5,7,10000,10000,10000,2},
                {10000,5,7,10000,10000,10000,2},
                {10000,5,7,10000,10000,10000,2},
                {10000,5,7,10000,10000,10000,2}
        };
        MGraph graph=new MGraph(verxs);//构建一个图
        MinTree minTree=new MinTree();
        minTree.createGraph(graph, verxs, data, weight);
        minTree.showGraph(graph);
    }
}
class MinTree{
    public void createGraph(MGraph graph,int verxs,char[]data,int[][]weighit) {
        int i,j;
        for(i=0;i<verxs;i++) {//以结点的个数为遍历条件
            graph.data[i]=data[i];//放入数据
            for(j=0;j<verxs;j++) {//内循环放入二维数组图
                graph.weight[i][j]=weighit[i][j];
            }
        }
    }
    public void showGraph(MGraph graph) {
        for(int[]link:graph.weight) {
            System.out.println(Arrays.toString(link));
        }
    }
}
class MGraph{
    int verxs;//表示图的节点个数
    char[]data;//存放节点数据
    int[][]weight;//存放边

    public MGraph(int verxs)
    {
        this.verxs=verxs;
        data=new char[verxs];
        weight=new int[verxs][verxs];
    }

}
package binarysearchnorecursion;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;

public class Test{
    public static void main(String[] args) {
        char[]data= {'A','B','C','D','E','F','G'};
        int verxs=data.length;
        int[][]weight=new int[][] {
                {10000,5,7,10000,10000,10000,2},//A
                {5,10000,10000,9,10000,10000,3},//B
                {7,10000,10000,10000,8,10000,10000},//C
                {10000,9,10000,10000,10000,4,10000},//D
                {10000,10000,8,10000,10000,5,4},//E
                {10000,10000,10000,4,5,10000,6},//F
                {2,3,10000,10000,4,6,10000}//G
        };
        MGraph graph=new MGraph(verxs);
        MinTree minTree=new MinTree();
        minTree.createGraph(graph, verxs, data, weight);
        minTree.showGraph(graph);
        minTree.prime(graph, 0);
    }
}
class MinTree{
    public void createGraph(MGraph graph,int verxs,char[]data,int[][]weighit) {
        int i,j;
        for(i=0;i<verxs;i++) {
            graph.data[i]=data[i];
            for(j=0;j<verxs;j++) {
                graph.weight[i][j]=weighit[i][j];
            }
        }
    }
    public void showGraph(MGraph graph) {
        for(int[]link:graph.weight) {
            System.out.println(Arrays.toString(link));
        }
    }
    public void prime(MGraph Graph,int v) {
        int visited[]=new int[Graph.verxs];
        visited[v]=1;
        int h1=-1;
        int h2=-2;
        int minWeight=10000;
        for(int k=1;k<Graph.verxs;k++) {
            for(int i=0;i<Graph.verxs;i++) {
                for(int j=0;j<Graph.verxs;j++) {
                    if(visited[i]==1&&visited[j]==0&&Graph.weight[i][j]<minWeight)
                    {
                        minWeight=Graph.weight[i][j];
                        h1=i;
                        h2=j;
                    }
                }
            }
            System.out.println("边"+Graph.data[h1]+"边"+Graph.data[h2]);
            visited[h2]=1;
            minWeight=10000;
        }
    }
}
class MGraph{
    int verxs;//表示图的节点个数
    char[]data;//存放节点数据
    int[][]weight;//存放边

    public MGraph(int verxs)
    {
        this.verxs=verxs;
        data=new char[verxs];
        weight=new int[verxs][verxs];
    }

}

8.克鲁斯卡尔算法 Kruskal

 



import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;

public class Test{
    private static final int INF = Integer.MAX_VALUE;//表示两个节点之间不是通路

    public static void main(String[] args) {
        char[]vertexs= {'A','B','C','D','E','F','G'};//七个站点
        int matrix[][]= {//打印七个站点之间的距离
                {0,12,INF,INF,INF,16,14},
                {12,0,10,INF,INF,7,INF},
                {INF,10,0,3,5,6,INF},
                {INF,INF,3,0,4,INF,INF},
                {INF,INF,5,4,0,2,8},
                {16,7,6,INF,2,0,9},
                {14,INF,INF,INF,8,9,0}};
        KruskalCase k=new KruskalCase(matrix, vertexs);//将矩阵和站点传进去
        k.print();

    }
}
class KruskalCase{
    private static final int INF=Integer.MAX_VALUE;
    private int [][]matrix;
    private char[]vertexs;
    private int edgeNum;
    public KruskalCase(int[][]matrix,char[]vertexs) {
        int len=vertexs.length;//获得站点个数
        this.matrix=new int[len][len];//创建和站点个数一样的二维数组
        this.vertexs=new char[len];//创建站点
        for(int i=0;i<len;i++) {//循环便利使得vertexs里面是站点
            this.vertexs[i]=vertexs[i];
        }
        for(int i=0;i<len;i++) {//遍历二维数组
            for(int j=0;j<len;j++) {
                this.matrix[i][j]=matrix[i][j];
            }
        }
        for(int i=0;i<len;i++) {//边的个数
            for(int j=0;j<len;j++) {
                if(this.matrix[i][j]!=INF) {
                    edgeNum++;
                }
            }
        }
    }
    public void print() {//打印二维数组
        System.out.println("邻接矩阵为:");
        for(int i=0;i<vertexs.length;i++) {
            for(int j=0;j<vertexs.length;j++) {
                System.out.print(matrix[i][j]+"             ");
            }
            System.out.println();
        }
    }
}


import java.util.Arrays;

// 表示图的边
class Edge {
    char start;
    char end;
    int weight;

    public Edge(char start, char end, int weight) {
        this.start = start;
        this.end = end;
        this.weight = weight;
    }

    @Override
    public String toString() {
        return "开始:" + start + "结束" + end ;
    }
}

// 实现Kruskal算法
class KruskalCase {
    private static final int INF = Integer.MAX_VALUE;
    private int[][] matrix;
    private char[] vertices;
    private int edgeCount;

    public KruskalCase(int[][] matrix, char[] vertices) {
        int len = vertices.length;
        this.matrix = new int[len][len];
        this.vertices = new char[len];
        // 复制顶点数组
        System.arraycopy(vertices, 0, this.vertices, 0, len);
        // 复制邻接矩阵
        for (int i = 0; i < len; i++) {
            System.arraycopy(matrix[i], 0, this.matrix[i], 0, len);
        }
        // 计算边的数量
        for (int i = 0; i < len; i++) {
            for (int j = i + 1; j < len; j++) {
                if (this.matrix[i][j] != INF) {
                    edgeCount++;
                }
            }
        }
    }

    // 打印邻接矩阵
    public void printMatrix() {
        System.out.println("邻接矩阵为:");
        for (int i = 0; i < vertices.length; i++) {
            for (int j = 0; j < vertices.length; j++) {
                System.out.printf("%10d", matrix[i][j]);
            }
            System.out.println();
        }
    }

    // 对边进行排序
    public void sortEdges(Edge[] edges) {
        Arrays.sort(edges, (e1, e2)
                -> e1.weight - e2.weight);
    }

    // 获取顶点的位置
    private int getVertexPosition(char ch) {
        for (int i = 0; i < vertices.length; i++) {//遍历全部顶点
            if (vertices[i] == ch) {//得到接受进来的顶点对应的索引
                return i;
            }
        }
        return -1;
    }

    // 获取所有边
    public Edge[] getEdges() {//打印所有边
        int index = 0;
        Edge[] edges = new Edge[edgeCount];
        for (int i = 0; i < vertices.length; i++) {
            for (int j = i + 1; j < vertices.length; j++) {
                if (matrix[i][j] != INF) {
                    edges[index++] = new Edge(vertices[i], vertices[j], matrix[i][j]);
                }
            }
        }
        return edges;
    }

    // 查找顶点所在的集合
    private int find(int[] parent, int i) {
        if (parent[i] == i) {
            return i;
        }
        return find(parent, parent[i]);
    }

    // 合并两个集合
    private void union(int[] parent, int x, int y) {
        int xroot = find(parent, x);//
        int yroot = find(parent, y);
        parent[xroot] = yroot;//把前面结点索引变成后面索引
    }

    // 实现Kruskal算法
    public Edge[] kruskalMST() {
        Edge[] result = new Edge[vertices.length - 1];//vertices.length个点,-1个边
        Edge[] edges = getEdges();//得到所有边
        sortEdges(edges);//给所有边按weight从小到大排序
        int[] parent = new int[vertices.length];
        for (int i = 0; i < vertices.length; i++) {
            parent[i] = i;
        }
        int e = 0;//表示最小生成树的边
        int i = 0;
        while (e < vertices.length - 1 && i < edges.length) {//当还存在边并且没有遍历到顶点-1条边
            Edge next_edge = edges[i];//获得第一条边
            int x = find(parent, getVertexPosition(next_edge.start));//求出该点对应的最终尾节点
            int y = find(parent, getVertexPosition(next_edge.end));//如上
            if (x != y) {//如果相同证明这条边构成了回路不执行
                result[e++] = next_edge;
                union(parent, x, y);
            }
            i++;
        }
        return result;
    }
}

// 测试类
public class Test {
    public static void main(String[] args) {
        char[] vertices = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};
        int[][] matrix = {
                {0, 12, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, 16, 14},
                {12, 0, 10, Integer.MAX_VALUE, Integer.MAX_VALUE, 7, Integer.MAX_VALUE},
                {Integer.MAX_VALUE, 10, 0, 3, 5, 6, Integer.MAX_VALUE},
                {Integer.MAX_VALUE, Integer.MAX_VALUE, 3, 0, 4, Integer.MAX_VALUE, Integer.MAX_VALUE},
                {Integer.MAX_VALUE, Integer.MAX_VALUE, 5, 4, 0, 2, 8},
                {16, 7, 6, Integer.MAX_VALUE, 2, 0, 9},
                {14, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, 8, 9, 0}
        };
        KruskalCase kruskal = new KruskalCase(matrix, vertices);
        kruskal.printMatrix();
        System.out.println("=");
        Edge[] edges = kruskal.getEdges();
        System.out.println("所有边: " + Arrays.toString(edges));
        System.out.println("=");
        kruskal.sortEdges(edges);
        System.out.println("所有边: " + Arrays.toString(edges));
        System.out.println("=");
        Edge[] mst = kruskal.kruskalMST();
        System.out.println("最小生成树的边: " + Arrays.toString(mst));
    }
}

9.迪杰斯特拉算法



import java.util.Arrays;

import javax.xml.transform.Templates;

public class Test {
    public static void main(String[] args) {
        char[]vertex= {'A','B','C','D','E','F','G'};
        int[][] matrix=new int[vertex.length][vertex.length];
        final int N=65535;
        matrix[0]=new int[] {N,5,7,N,N,N,2};
        matrix[1]=new int[] {5,N,N,9,N,N,3};
        matrix[2]=new int[] {7,N,N,N,8,N,N};
        matrix[3]=new int[] {N,9,N,N,N,4,N};
        matrix[4]=new int[] {N,N,8,N,N,5,4};
        matrix[5]=new int[] {N,N,N,4,5,N,6};
        matrix[6]=new int[] {2,3,N,N,4,6,N};
        //创建Graph对象
        Graph garph=new Graph(vertex,matrix);
        garph.showGraph();
        System.out.println();
        garph.dsj(6);
        garph.showDisjsta();
    }
}
class Graph{
    private char[]vertex;//顶点数组
    private int[][]matrix;//邻接矩阵
    private VisitedVertex vv;
    public Graph(char[]vertex,int[][]matrix) {
        this.matrix=matrix;
        this.vertex=vertex;
    }
    public void showDisjsta() {
        vv.show();
    }
    //显示图
    public void showGraph() {
        for(int[]link:matrix) {
            System.out.println(Arrays.toString(link));
        }
    }
    public void dsj(int index) {
        vv=new VisitedVertex(vertex.length, index);
        update(index);//更新index顶点到周围定带你的距离和前驱节点
        for(int j=1;j<vertex.length;j++) {//遍历完所有节点,优先获得距离出发节点近的
            index=vv.updateArr();//选择并返回新的结点第一次循环得到距离出发顶点最近的索引
            update(index);//更新index下标顶点到周围顶点的距离和周围顶点的前驱节点
        }
    }
    //	更新index下标顶点到周围顶点的距离和周围顶点的前驱节点
    public void update(int index) {
        int len=0;
        //根据遍历我们的邻接矩阵matrix[index]行
        for(int j=0;j<matrix[index].length;j++) {//遍历所有顶点
            //len 出发顶点到index顶点的距离+从index顶点到j顶点的距离之和
            len=vv.getDis(index)+matrix[index][j];
            //如果j顶点没有被访问过,并且len小于出发顶点到j顶点的距离,就需要更新
            if(!vv.in(j)&&len<vv.getDis(j)) {//j顶点没有被访问过并且len<出发顶点到j顶点的距离
                vv.updatePre(j, index);
                vv.updateDis(j, len);
            }
        }
    }
}



class VisitedVertex{
    //记录各个顶点是否访问过,1表示访问过,0表示未访问,会动态更新
    public int[]already_arr;
    //每个下标对应的值为前一个顶点的下标,会动态更新
    public int[]pre_visited;
    //记录从出发顶点到其他所有顶点的距离,比如G为出发顶点,就会记录G到其他顶点的距离
    //会动态更新,求的最短距离就会存放到dis
    public int[]dis;

    public VisitedVertex(int length,int index) {
        this.already_arr=new int[length];
        this.pre_visited=new int[length];
        this.dis=new int[length];
        //初始化 dis数组
        Arrays.fill(dis, 65535);
        this.already_arr[index]=1;//设置出发顶点被访问过
        dis[index]=0;//设置出发顶点的访问距离为0
    }
    /*判断index顶点是否被访问过*/
    public boolean in(int index) {
        return already_arr[index]==1;
    }
    //	更新出发顶点到index的距离
    public void updateDis(int index,int len) {
        dis[index]=len;
    }
    //	更新顶点的前驱为index结点
    public void updatePre(int pre,int index) {
        pre_visited[pre]=index;
    }
    //	返回出发顶点到index顶点的距离
    public int getDis(int index) {
        return dis[index];
    }

    public int updateArr() {
        int min=65535,index=0;
        for(int i=0;i<already_arr.length;i++) {//遍历得到g周围最近的结点的索引并把该结点标志为访问过
            if(already_arr[i]==0&&dis[i]<min) {//节点没被访问过并且到g可以连接的到
                min=dis[i];//让min等于该节点到出发顶点的距离
                index=i;//
            }
        }
        already_arr[index]=1;
        return index;
    }
    //显示最后的结果
    //即将三个数组情况输出
    public void show() {
        System.out.println("==================");
        //输出already_arr
        for(int i:already_arr) {
            System.out.print(i+" ");
        }System.out.println();
        for(int i:pre_visited) {
            System.out.print(i+" ");
        }System.out.println();
        for(int i:dis) {
            System.out.print(i+" ");
        }
        System.out.println();
        char[]vertex= {'A','B','C','D','E','F','G'};
        int count=0;
        for(int i:dis) {
            if(i!=65535) {
                System.out.print(vertex[count]+"("+i+")");
            }else {
                System.out.println("N ");
            }count++;
        }
        System.out.println();
    }
}

 

10.弗洛伊德算法(Floyd)

 

package binarysearchnorecursion;

import java.util.Arrays;

public class Main {
	public static void main(String[] args) {
		char[]vertex= {'A','B','C','D','E','F','G'};
		int[][]matrix=new int[vertex.length][vertex.length];
		final int N=65535;
		matrix[0]=new int[] {0,5,7,N,N,N,2};
		matrix[1]=new int[] {5,0,N,9,N,N,3};
		matrix[2]=new int[] {7,N,0,N,8,N,N};
		matrix[3]=new int[] {N,9,N,0,N,4,N};
		matrix[4]=new int[] {N,N,8,N,0,5,4};
		matrix[5]=new int[] {N,N,N,4,5,0,6};
		matrix[6]=new int[] {2,3,N,N,4,6,0};
		Graph graph=new Graph(vertex.length,matrix,vertex);
		graph.show();
		}
	}
class Graph{
	private int[][] dis;//保存各个顶点到各个顶点的距离 最后结果也保留在这里
	private char []vertex;//保存顶点数组
	private int[][]pre;//保存目标顶点的前驱顶点
	
	public Graph(int length,int[][]matrix,char[]vertex) {
		this.dis=matrix;
		this.vertex=vertex;
		this.pre=new int[length][length];
		//对pre数组进行初始化
		for(int i=0;i<length;i++) {
			Arrays.fill(pre[i], i);
		}
	}
	public void show() {
		char[]vertex= {'A','B','C','D','E','F','G'};
		for(int k=0;k<dis.length;k++) {
			for(int i=0;i<dis.length;i++) {
				System.out.print(vertex[pre[k][i]]+"  ");
			}System.out.println();
			for(int i=0;i<dis.length;i++) {
				System.out.print("("+vertex[k]+")"+"到"+vertex[i]+"的距离是"+dis[k][i]+" ");
			}System.out.println();
			System.out.println();
		}
	}
	public void floyd() {
		int len=0;
		for(int k=0;k<dis.length;k++) {//k为中间顶点
			for(int i=0;k<dis.length;i++) {
				for(int j=0;k<dis.length;j++) {
					len=dis[i][k]+dis[k][j];
					if(len<dis[i][j]) {
						dis[i][j]=len;//更新距离
						pre[i][j]=pre[k][j];//更新前驱节点
					}
				}
			}
		}
	}
}

http://www.dtcms.com/a/98237.html

相关文章:

  • 自动化与智能化的认知差异
  • 【即插即用涨点模块-卷积】SPDConv空间深度卷积,助力小目标与低分辨有效涨点【附源码+注释】
  • 28_跨域
  • Android设计模式之模板方法模式
  • 如何在 AI 搜索引擎(GEO)霸屏曝光,快速提升知名度?
  • RabbitMQ高级特性--重试特性
  • 【C++初阶】第12课—list
  • 人工智能入门(1)
  • 字符和字符串的输入方式
  • 安当SLAc操作系统安全登录解决方案:破解设备供应商Windows权限失控困局
  • 全自动数字网络机器人:重塑未来的无形引擎 ——从金融量化到万物互联,为何必须“ALL IN”?
  • MySQL 中的表连接(JOIN)详解
  • 六十天前端强化训练之第三十五天之Jest单元测试大师课:从入门到实战
  • 【C++20】format格式化输出
  • 每日一题 == 674. 最长连续递增序列
  • 26_ajax
  • qgis点从面图层上拾取属性
  • NLP高频面试题(二十四)——RAG相关内容简介
  • 【Java】public class Person{}和public Person{} 和 public Person person究竟都有哪些区别呢。
  • Java---类与对象
  • NLP高频面试题(二十三)对抗训练的发展脉络,原理,演化路径
  • 关于跨域与.NET的处理方案
  • 软考-高级-系统架构设计师【考试备考资料下载】
  • 自学-408-《计算机网络》(总结速览)
  • 区块链在教育领域的创新应用:改变传统教育的未来
  • 黑盒测试的等价类划分法(输入数据划分为有效的等价类和无效的等价类)
  • 综合实验
  • qt之使用redis与其他程序(python)交互同通信
  • 基于SpringBoot实现的高校实验室管理平台功能四
  • 多线程 -- Thread类