常用的10中算法

本文介绍了非递归实现的二分查找,分治算法在汉诺塔问题的应用,KMP字符串匹配算法,贪心算法解决广播电台覆盖问题,以及普里姆和克鲁斯卡尔构造最小生成树的算法。通过这些实例展示了不同算法在解决实际问题中的应用和思想。
摘要由CSDN通过智能技术生成

二分查找[ 非递归 ]

/**
 * 二分查找非递归实现
 *
 * @author qb
 * @version 1.0
 * @since 2022/3/7 11:30
 */
public class BinarySearchNoRecur {

    public static void main(String[] args) {

        int[] arr = {1,3,8,10,11,67,100};
        int i = binarySearch(arr, 100);
        System.out.println(i);

    }

    /**
     *
     * @param arr 带查找的数组,是升序的
     * @param target 需要查找的数据
     * @return 对应下标  -1表示没有找到
     */
    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;
    }

}

分治算法

在这里插入图片描述
在这里插入图片描述

/**
 * 分治算法
 *
 * @author qb
 * @version 1.0
 * @since 2022/3/7 13:34
 */
public class DAC {

    public static void main(String[] args) {
        hanoiTower(5,'A','B','C');
    }

    //汉诺塔的移动方法
    //使用分治算法
    public static void hanoiTower(int num,char a,char b,char c){

        if(num == 1){
            System.out.println("第一个盘从 "+ a + "->" +c);
        }else{
            hanoiTower(num -1,a,c,b);
            System.out.println("第" +num +"个盘从 "+a +"->"+c);
            hanoiTower(num-1,b,a,c);
        }

    }

}

KMP算法

在这里插入图片描述

/**
 * KMP算法
 *
 * @author qb
 * @version 1.0
 * @since 2022/3/8 10:51
 */
public class KMPAlgorithm {

    public static void main(String[] args) {

        String str1 = "BBC ABCDAB ABCDABCDABDE";
        String str2 = "ABCDABD";
        System.out.println();
        int[] nest = kmpNext("ABCDABD");
        System.out.println(Arrays.toString(nest));

//        int bBc = kmpSearch(str1, str2, nest);
//        System.out.println(bBc);
    }

    /**
     * kmp的搜索算法
     * @param str1 源字符串
     * @param str2 子串
     * @param next 部分匹配表,子串对应的部分匹配表
     * @return int -1没有匹配到 ,反之返回第一个匹配的位置
     */
    public static int kmpSearch(String str1,String str2,int[] next){

        //遍历
        for (int i = 0,j=0; i < str1.length(); i++) {
            //需要处理 str1.charAt(i) != str2.charAt(j)
            //KMP 的核心,去调整j的大小
            while ( j > 0 && str1.charAt(i) != str2.charAt(j)){
                j = next[j-1];
            }
            if(str1.charAt(i) == str2.charAt(j)){
                j++;
            }
            if(j == str2.length()){
                return i - j +1;
            }
        }
        return -1;
    }


    /**
     * 获取一个字符串的部分匹配值
     */
    public static int[] kmpNext(String dest){
        //创建一个数组,保存部分匹配值
        int[] next = new int[dest.length()];
        //如果字符串长度为1,部分匹配值就是0
        next[0] = 0;
        for (int i = 1,j=0; i < dest.length(); i++) {
            System.out.println("for: "+ dest.charAt(i)+","+dest.charAt(j));
            //当dest.charAt(i) != dest.charAt(j)时,我们需要从next[j-1],获取新的节点,
            // 直到我们发现有dest.charAt(i) == dest.charAt(j)条件满足时退出
            while (j > 0 && dest.charAt(i) != dest.charAt(j)){
                System.out.println("while: "+ dest.charAt(i)+","+dest.charAt(j));
                //kmp算法的核心 TODO: 此处的意思还不是很懂
                j = next[j-1];
            }
            //当条件满足时,部分匹配值就是要+1
            if(dest.charAt(i) == dest.charAt(j)){
                j++;
            }
            next[i] = j;
        }
        return next;
    }


}

贪心算法

在这里插入图片描述
在这里插入图片描述

/**
 * 贪心算法
 *
 * @author qb
 * @version 1.0
 * @since 2022/3/8 13:59
 */
public class Greedy {
    public static void main(String[] args) {

        //创建广播电台  ,放入到map中
        HashMap<String, HashSet<String>> broadcasts = new HashMap<>();
        //将各个电台放入到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("大连");

        //加入到map
        broadcasts.put("k1",hashSet1);
        broadcasts.put("k2",hashSet2);
        broadcasts.put("k3",hashSet3);
        broadcasts.put("k4",hashSet4);
        broadcasts.put("k5",hashSet5);


        HashSet<String> allAreas = new HashSet<>();
        allAreas.add("北京");
        allAreas.add("上海");
        allAreas.add("天津");
        allAreas.add("广州");
        allAreas.add("深圳");
        allAreas.add("成都");
        allAreas.add("杭州");
        allAreas.add("大连");

        //创建arrayList存放选择的电台集合
        List<String> selects = new ArrayList<>();

        //定义一个;临时的集合,在遍历的过程中,存放遍历过程中的电台覆盖的地区和当前还没有覆盖的地区的交集
        HashSet<String> tempSet = new HashSet<>();

        //定义maxKey,保存在一次遍历过程中,能够覆盖最大未覆盖的地区对应的电台的key
        String maxKey ;
        //如果maxKey不为null,则会放入到selects
        while (allAreas.size() != 0){
            //如果allAreas 不为0,则表示还没有覆盖到所有的地区
            maxKey = null;
            //遍历
            for (String key : broadcasts.keySet()){
                HashSet<String> areas = broadcasts.get(key);
                tempSet.clear();
                tempSet.addAll(areas);
                //求出两个tempSet和 allAreas的交集,交集会赋给tempSet
                tempSet.retainAll(allAreas);
                //如果当前的集合包含的未覆盖地区的数量,比maxKey的指向的集合的地区还多
                //就需要重置maxKey
                // tempSet.size() > broadcasts.get(maxKey).size() 体现贪心算法
                if(tempSet.size() > 0 &&
                        (maxKey == null || tempSet.size() > broadcasts.get(maxKey).size())){
                        maxKey = key;
                }
            }
            //maxKey != null ,就应该将maxKey 加入selects
            if(maxKey != null){
                selects.add(maxKey);
                //将maxKey指向的集合,从allAreas中去掉
                allAreas.removeAll(broadcasts.get(maxKey));
            }


        }
        //[k1,k2,k3,k5]
        System.out.println("得到的结果:"+selects);


    }
}

普里姆算法 [ MST ]

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

/**
 * 普里姆算法
 *
 * @author qb
 * @version 1.0
 * @since 2022/3/8 15:17
 */
public class PrimAlgorithm {

    public static void main(String[] args) {

        //创建图
        char[] data = new char[]{'A','B','C','D','E','F','G'};
        int verxs = data.length;
        //邻接矩阵的关系
        int[][] weight = new int[][]{
                /*A*/  /*B*/  /*C*/  /*D*/  /*E*/   /*F*/  /*G*/
          /*A*/{10000,   5,     7,   10000, 10000,  10000,  2},
          /*B*/{5,     10000, 10000,   9,   10000,  10000,  3},
          /*C*/{7,     10000, 10000, 10000,   8,    10000,  10000},
          /*D*/{10000,   9,   10000, 10000, 10000,    4,    10000},
          /*E*/{10000, 10000,   8,   10000, 10000,    5,    4},
          /*F*/{10000, 10000, 10000,   4,     5,    10000,  6},
          /*G*/{2,       3,   10000, 10000,   4,      6,    10000}
        };
        MGraph mGraph = new MGraph(verxs);
        MinTree minTree = new MinTree();
        minTree.createGraph(mGraph,verxs,data,weight);
        minTree.showGraph(mGraph);

        //
        minTree.prim(mGraph,1);
    }

}

/**
 * 创建最小生成树
 */
class MinTree{

    /**
     *
     * @param graph 图对象
     * @param verxs 图对应的顶点个数
     * @param data  图的各个定点的值
     * @param weight 图的邻接矩阵
     */
    public void createGraph(MGraph graph,int verxs,char[] data,int[][] weight){

        int i,j;
        for (i=0;i<verxs;i++){
            graph.data[i] = data[i];
            for (j = 0; j < verxs ; j++) {
                graph.weight[i][j] = weight[i][j];
            }
        }

    }

    /**
     * 显示图
     */
    public void showGraph(MGraph graph){
        for (int[] link : graph.weight)
        {
            System.out.println(Arrays.toString(link));
        }
    }


    /**
     * 编写pirm,得到最小生成树
     * @param graph 图
     * @param v 表示从图的第几个定点开始生成
     */
    public void prim(MGraph graph,int v){
        //标记定点是否被访问过
        int[] visited = new int[graph.verxs];
        //把当前节点标记为已访问
        visited[v] = 1;
        //用h1和h2记录两个顶点的下标
        int h1 = -1;
        int h2 = -1;
        int minWeight = 10000;
        for (int k = 1; k < graph.verxs; k++) {
            //因为有 graph.verxs 个顶点,普里姆算法结束后,有 graph.verxs - 1 条边

            //这个是确定每一次生成的子图,和哪儿个节点的距离最近
            for (int i = 0; i < graph.verxs; i++) {
                // i 节点标识被访问过的顶点
                for (int j = 0; j < graph.verxs; j++) {
                    // j 还没有访问过的节点
                    if(visited[i] == 1 && visited[j] == 0 && graph.weight[i][j] < minWeight){
                        //寻找 i 与未访问过的j的最小的值
                        minWeight = graph.weight[i][j];
                        h1 = i;
                        h2 = j;
                    }
                }
            }

            //找打最小的边
            System.out.println("边 <"+graph.data[h1]+","+graph.data[h2] +"> 权值" +minWeight);
            visited[h2] = 1;
            // minWeight 重新设置
            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];
    }

}

克鲁斯卡尔算法

在这里插入图片描述
在这里插入图片描述

/**
 * 克鲁斯特尔
 *
 * @author qb
 * @version 1.0
 * @since 2022/3/8 16:33
 */
public class KruskalCase {

    /**
     * 边的个数
     */
    private int edgeNum;

    /**
     * 顶点数组
     */
    private char[] vertexs;

    /**
     * 邻接矩阵
     */
    private int[][] matrix;

    /**
     * 表示两个顶点不能连通
     */
    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 = {
             /*A*/ /*B*/ /*C*/ /*D*/ /*E*/ /*F*/ /*G*/
        /*A*/{ 0,    12,  INF,  INF,  INF,   16,   14},
        /*B*/{ 12,    0,   10,  INF,  INF,    7,   INF},
        /*C*/{ INF,  10,    0,    3,    5,    6,   INF},
        /*D*/{ INF,  INF,   3,    0,    4,   INF,  INF},
        /*E*/{ INF,  INF,   5,    4,    0,     2,    8},
        /*F*/{  16,    7,   6,  INF,    2,     0,    9},
        /*G*/{  14,  INF, INF,  INF,    8,     9,    0}
        };

        //创建实例
        KruskalCase kruskalCase = new KruskalCase(vertexs, matrix);
        kruskalCase.print();
        EData[] edges = kruskalCase.getEdges();
        kruskalCase.kruskal();

    }

    public KruskalCase(char[] vertexs,int[][] matrix){
        //初始化定点数和边的个数
        int vLen = vertexs.length;
        //初始化顶点
        this.vertexs = new char[vLen];
        for (int i = 0; i < vertexs.length; i++) {
            this.vertexs[i] = vertexs[i];
        }
        //初始化边
        this.matrix = new int[vLen][vLen];
        for (int i = 0; i < vLen; i++) {
            for (int j = 0; j < vLen; j++) {
                this.matrix[i][j] = matrix[i][j];
            }
        }
        //统计边
        for (int i = 0; i < vLen; i++) {
            for (int j = i+1; j < vLen; j++) {
                if(this.matrix[i][j] != INF){
                    edgeNum ++ ;
                }
            }
        }
    }

    public void kruskal(){
        //标识最后结果数组的索引
        int index = 0;
        //用于保存已有最小生成树中的每个顶点在最小生成树中的终点
        int[] ends = new int[edgeNum];
        //创建结果数组,保存最后的最小生成树
        EData[] rets = new EData[edgeNum];
        //获取图中所有的边的集合,一共有12条边
        EData[] edges = getEdges();
        System.out.println(Arrays.toString(edges));

        //按照边的权值大小进行排序
        sortEdge(edges);

        //遍历edges 数组,将边添加到最小生成树中,判断是否形成了回路,没有就加入rets
        for (int i = 0; i < edgeNum; i++) {
            //获取到第i条边的第一个顶点(起点)
            int p1 = getPosition(edges[i].start);
            //获取到第i条边的第二个顶点(起点)
            int p2 = getPosition(edges[i].end);
            //获取p1这个顶点在已生成的最小生成树中的终点
            int m = getEnd(ends,p1);
            //获取p2在已有最小生成树中的终点
            int n = getEnd(ends,p2);
            //判断是否构成回路
            if(m != n){
                //说明不够成回路
                //设置m 在“已有最小生成树”中的终点
                ends[m] = n;
                //有一条边加入到rets中
                rets[index++] = edges[i];
            }

        }
        System.out.println("最小生成树为:");
        for (int i = 0; i < index; i++) {
            System.out.println(rets[i]);
        }
    }

    public void print(){
        System.out.println("邻接矩阵为:");
        for (int i = 0; i < vertexs.length; i++) {
            for (int j = 0; j < vertexs.length; j++) {
                System.out.printf("%12d\t",matrix[i][j]);
            }
            System.out.println();
        }
    }

    /**
     * 对边进行排序处理,冒泡
     */
    private void sortEdge(EData[] edges){

        for (int i = 0; i < edges.length - 1; i++) {
            for (int j = 0; j < edges.length - 1 - i; j++) {
                if(edges[j].weight > edges[j+1].weight){
                    EData tmp = edges[j];
                    edges[j] = edges[j + 1];
                    edges[j+1] = tmp;
                }
            }
        }

    }

    /**
     *
     * @param ch 传入的顶点的值
     * @return 返回的ch对应的下标, -1为未找到
     */
    public int getPosition(char ch){

        for (int i = 0; i < vertexs.length; i++) {
            if(vertexs[i] == ch){
                return i;
            }
        }

        return -1;

    }

    /**
     * 获取图中的边,放到EData数组中,后面我们需要遍历该数组
     * 是通过matrix邻接矩阵来获取
     * EData[] -> [['A','B',12],['B','F',7]]
     * @return
     */
    private EData[] getEdges(){

        int index =0;
        EData[] edges = new EData[edgeNum];

        for (int i = 0; i < vertexs.length; i++) {
            for (int j = i+1; j < vertexs.length ; j++) {
                if(matrix[i][j] != INF){
                    edges[index++] = new EData(vertexs[i],vertexs[j],matrix[i][j]);
                }
            }
        }
        return edges;
    }

    /**
     * 获取下标为i的顶点的终点,用于判断后面两个顶点的中间是否相同
     * @param ends 记录了各个顶点对应的终点是哪儿个,ends 是在遍历过程中逐步形成的
     * @param i 传入的顶点对应的下标
     * @return 下标为i的,这个顶点对应的终点的下标
     */
    private int getEnd(int[] ends,int i){

        while (ends[i] != 0){
            i = ends[i];
        }
        return i;

    }



}

/**
 * 对象实例表示 一条边
 */
class EData{
    /**
     * 边的起点
     */
    char start;

    /**
     * 边的终点
     */
    char end;

    /**
     * 边的权值
     */
    int weight;

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

    @Override
    public String toString() {
        return "EData{" +
                "<" + start +
                ", " + end +
                "> =weight=" + weight +
                '}'+"\t";
    }
}

骑士周游问题

在这里插入图片描述
在这里插入图片描述

/**
 * 马踏棋盘
 * @author qb
 * @version 1.0
 * @since 2022/3/9 9:45
 */
public class HorseChessBoard {

    /**
     * 棋盘的列
     */
    private static int X;

    /**
     * 棋盘的行
     */
    private static int Y;

    /**
     * 标记棋盘的各个位置是否被访问过
     */
    private static boolean visited[];

    /**
     * 是否棋盘的所有位置都被访问了
     */
    private static boolean finished = false;

    public static void main(String[] args) {
        System.out.println("start");
        X = 6;
        Y = 6;
        //马儿走的初始位置的行
        int row = 2;
        //马儿走的初始位置的列
        int column = 4;
        //创建棋盘
        int[][] chessBoard = new int[X][Y];
        visited = new boolean[X*Y];
        //
        long start = System.currentTimeMillis();
        traversalChessBoard(chessBoard,row-1,column-1,1);
        long end = System.currentTimeMillis();
        System.out.println("共耗时: "+ (end - start)/1000 +" s");
        //输出棋盘的最后情况
        for (int[] rows: chessBoard) {
            for (int step :rows){
                System.out.print(step +"\t");
            }
            System.out.println();
        }
    }



    /**
     * 骑士周游问题的算法
     * @param chessBoard 棋盘
     * @param row 马儿当前位置的行  从0开始
     * @param column 马儿当前位置的列 从 0
     * @param step 马儿走到了第几步,初始位置就是第一步
     */
    public static void traversalChessBoard(int[][] chessBoard,int row,int column,int step){

        chessBoard[row][column] = step;
        //马儿当前的位置
        visited[row * X + column] = true;
        //获取当前可以走的下一个位置的集合,此处column就是x 列, row就是行y
        List<Point> ps = next(new Point(column, row));
        //遍历ps
        while (!ps.isEmpty()){
            //取出下一个可以走的位置
            Point p = ps.remove(0);
            //判断是否已经访问过
            if(!visited[p.y * X +p.x]){
                traversalChessBoard(chessBoard,p.y,p.x,step+1);
            }
        }
        //判断马儿是否完成了任务,使用step 和应该走的步数比较
        //如果没有打到数量,则表示没有完成任务,将整个棋盘置0
        if(step < X*Y && !finished){
            chessBoard[row][column] = 0;
            visited[row*X+column] = false;
        }else{
            finished = true;
        }
    }


    /**
     * 根据当前的位置,计算马儿还能走哪儿些位置,并放在list中,最多有8个位置
     * @param curPoint 当前点
     * @return List<Point> 可走的点集合
     */
    public static List<Point> next(Point curPoint){

        List<Point> ps = new ArrayList<>();
        //创建一个point
        Point p1 = new Point();
        // curPoint.x - 2 向左移动两列,curPoint.y-1 向上移动一行
        // 表示马儿可以走 5
        if((p1.x = curPoint.x - 2) >=0 && (p1.y = curPoint.y-1) >=0){
            ps.add(new Point(p1));
        }
        //判断马儿能不能走6
        if((p1.x = curPoint.x - 1) >=0 && (p1.y = curPoint.y-2) >=0){
            ps.add(new Point(p1));
        }
        //判断马儿能不能走7
        if((p1.x = curPoint.x + 1) < X && (p1.y = curPoint.y-2) >=0){
            ps.add(new Point(p1));
        }
        //判断马儿能不能走0
        if((p1.x = curPoint.x + 2) < X && (p1.y = curPoint.y-1) >=0){
            ps.add(new Point(p1));
        }
        //判断马儿能不能走1
        if((p1.x = curPoint.x + 2) < X && (p1.y = curPoint.y + 1) < Y){
            ps.add(new Point(p1));
        }
        //判断马儿能不能走2
        if((p1.x = curPoint.x + 1) < X && (p1.y = curPoint.y + 2) < Y){
            ps.add(new Point(p1));
        }
        //判断马儿能不能走3
        if((p1.x = curPoint.x - 1) >= 0 && (p1.y = curPoint.y + 2) < Y){
            ps.add(new Point(p1));
        }
        //判断马儿能不能走4
        if((p1.x = curPoint.x - 2) >= 0 && (p1.y = curPoint.y + 1) < Y){
            ps.add(new Point(p1));
        }
        return ps;
    }

}

贪心算法优化

/**
 * 马踏棋盘
 * @author qb
 * @version 1.0
 * @since 2022/3/9 9:45
 */
public class HorseChessBoard {

    /**
     * 棋盘的列
     */
    private static int X;

    /**
     * 棋盘的行
     */
    private static int Y;

    /**
     * 标记棋盘的各个位置是否被访问过
     */
    private static boolean visited[];

    /**
     * 是否棋盘的所有位置都被访问了
     */
    private static boolean finished = false;

    public static void main(String[] args) {
        System.out.println("start");
        X = 8;
        Y = 8;
        //马儿走的初始位置的行
        int row = 1;
        //马儿走的初始位置的列
        int column = 1;
        //创建棋盘
        int[][] chessBoard = new int[X][Y];
        visited = new boolean[X*Y];
        //
        long start = System.currentTimeMillis();
        traversalChessBoard(chessBoard,row-1,column-1,1);
        long end = System.currentTimeMillis();
        System.out.println("共耗时: "+ (end - start)/1000 +" s");
        //输出棋盘的最后情况
        for (int[] rows: chessBoard) {
            for (int step :rows){
                System.out.print(step +"\t");
            }
            System.out.println();
        }
    }



    /**
     * 骑士周游问题的算法
     * @param chessBoard 棋盘
     * @param row 马儿当前位置的行  从0开始
     * @param column 马儿当前位置的列 从 0
     * @param step 马儿走到了第几步,初始位置就是第一步
     */
    public static void traversalChessBoard(int[][] chessBoard,int row,int column,int step){

        chessBoard[row][column] = step;
        //马儿当前的位置
        visited[row * X + column] = true;
        //获取当前可以走的下一个位置的集合,此处column就是x 列, row就是行y
        List<Point> ps = next(new Point(column, row));
        //对ps排序,排序的规则就是堆ps的所有的point对象的下一步位置的数目,进行非递归排序
        sort(ps);
        System.out.println(ps);
        //遍历ps
        while (!ps.isEmpty()){
            //取出下一个可以走的位置
            Point p = ps.remove(0);
            //判断是否已经访问过
            if(!visited[p.y * X +p.x]){
                traversalChessBoard(chessBoard,p.y,p.x,step+1);
            }
        }
        //判断马儿是否完成了任务,使用step 和应该走的步数比较
        //如果没有打到数量,则表示没有完成任务,将整个棋盘置0
        if(step < X*Y && !finished){
            chessBoard[row][column] = 0;
            visited[row*X+column] = false;
        }else{
            finished = true;
        }
    }


    /**
     * 根据当前的位置,计算马儿还能走哪儿些位置,并放在list中,最多有8个位置
     * @param curPoint 当前点
     * @return List<Point> 可走的点集合
     */
    public static List<Point> next(Point curPoint){

        List<Point> ps = new ArrayList<>();
        //创建一个point
        Point p1 = new Point();
        // curPoint.x - 2 向左移动两列,curPoint.y-1 向上移动一行
        // 表示马儿可以走 5
        if((p1.x = curPoint.x - 2) >=0 && (p1.y = curPoint.y-1) >=0){
            ps.add(new Point(p1));
        }
        //判断马儿能不能走6
        if((p1.x = curPoint.x - 1) >=0 && (p1.y = curPoint.y-2) >=0){
            ps.add(new Point(p1));
        }
        //判断马儿能不能走7
        if((p1.x = curPoint.x + 1) < X && (p1.y = curPoint.y-2) >=0){
            ps.add(new Point(p1));
        }
        //判断马儿能不能走0
        if((p1.x = curPoint.x + 2) < X && (p1.y = curPoint.y-1) >=0){
            ps.add(new Point(p1));
        }
        //判断马儿能不能走1
        if((p1.x = curPoint.x + 2) < X && (p1.y = curPoint.y + 1) < Y){
            ps.add(new Point(p1));
        }
        //判断马儿能不能走2
        if((p1.x = curPoint.x + 1) < X && (p1.y = curPoint.y + 2) < Y){
            ps.add(new Point(p1));
        }
        //判断马儿能不能走3
        if((p1.x = curPoint.x - 1) >= 0 && (p1.y = curPoint.y + 2) < Y){
            ps.add(new Point(p1));
        }
        //判断马儿能不能走4
        if((p1.x = curPoint.x - 2) >= 0 && (p1.y = curPoint.y + 1) < Y){
            ps.add(new Point(p1));
        }
        return ps;
    }


    /**
     * 根据当前这一步的所有的下一步的选择的位置,进行非递减排序
     * 减少回溯的次数, 贪心算法想用最少的回溯
     */
    public static void sort(List<Point> ps){
        ps.sort((o1, o2) -> {
            //获取到o1的下一步的所有位置的个数
            int count1 = next(o1).size();
            int count2 = next(o2).size();
            if(count1 < count2){
                return -1;
            }
            else if(count1 == count2){
                return 0;
            }
            return 1;
        });
    }

}

动态规划算法[ 后期补充 ]

迪杰斯特拉算法[ 后续补上 ]

弗洛伊德算法 [ 后续补上 ]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值