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

java后端开发day29--常见算法(一)----查找与排序

在这里插入图片描述
(以下内容全部来自上述课程)
在这里插入图片描述

1.查找算法

1.基本查找

数据无 顺序要求。

package search;

public class BasicSearchDemo1 {
    public static void main(String[] args) {
        //基本查找/顺序查找
        //核心:
        //从0索引开始挨个往后查找

        //需求:定义一个方法利用基本查找,查询某个元素是否存在
        //数据如下:{131, 127, 147, 81, 103, 23, 7, 79}
        int[] arr = {131, 127, 147, 81, 103, 23, 7, 79};
        int number = 82;
        System.out.println(basicSearch(arr, number));

    }
    //参数:
    //一:数组
    //二:要查找的元素
    //返回值:
    //元素是否存在
    public static boolean basicSearch(int[] arr, int number){
        //利用基本查找,查询某个元素是否存在
        //数据如下:{131, 127, 147, 81, 103, 23, 7, 79}
        for(int i = 0; i < arr.length; i++){
            if(arr[i] == number){
                return true;
            }
        }
        return false;
    }
}

2.二分查找/折半查找

  • 前提条件:数组中的数据必须是有序的。
    如果数据是乱的,先排序再用二分查找得到的索引没有实际意义,只能确定当前数字在数组中是否存在,因为排序之后数字的位置就可能发生变化了。
  • 核心逻辑:每次排除一半的查找范围。
  • 提高查找效率

请添加图片描述

package search;

public class BinarySearchDemo1 {

	public static void main(String[] args) {
		// 二分查找/折半查找
		// 核心:
		// 每次排除一半的查找范围
		// 前提:数组元素有序
		// 需求:定义一个方法利用二分查找,查询某个元素是否存在
		// 数据如下:{1,2,3,4,5,6,7,8,9}
		int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
		int index = binarySearch(arr, 8);
		System.out.println(index);
	}
	public static int binarySearch(int[] arr, int value) {
		// 定义三个变量记录要查找的范围
        int min = 0;
		int max = arr.length - 1;

        // 循环查找,min大于max时结束查找
        // 检查中间值是否是要找的
        // 中间值比要找的值大,说明要找的值在左边
        // 中间值比要找的值小,说明要找的值在右边
        // 重新计算min和max
		while (true) {
            if (min > max) {
                return -1;
            }
            int mid = (min + max) / 2;
            if (arr[mid] > value) {
                max = mid - 1;
            } else if (arr[mid] < value) {
                min = mid + 1;
            } else {
                return mid;
            }
        }
	}
}

3.插值查找(二分查找优化1----了解)

只能数据分布均匀才能用。
请添加图片描述

4.斐波那契(二分查找优化2----了解)

请添加图片描述

5.分块查找

  • 分块原则1:前一块中的最大数据,小于后一块中所有的数据。(块内无序,块间有序)
  • 分块原则2:块数数量一般等于数字的个数开根号。比如:16个数字一般分为4块左右。
  • 核心思路:先确定要查找的元素在哪一块,然后在块内挨个查找。

请添加图片描述

package search;

public class BlockSearchDemo {
    public static void main(String[] args) {
        //分块查找
        //核心:
        //1、必须要知道索引表的内容
        //2、先去索引表中找,确定要找的数据在哪一个块中
        //3、再去这个块中找对应的元素
        int[] arr = {16, 5, 9, 12, 21, 18,
                32, 23, 37, 26, 45, 34,
                50, 48, 61, 52, 73, 66};
        //创建三个块的对象
        //每个块的对象中包含了三个值:最大值、起始索引、结束索引
        Block b1 = new Block(21, 0, 5);
        Block b2 = new Block(45, 6, 11);
        Block b3 = new Block(73, 12, 17);
        //定义一个数组用来存储三个块的对象
        Block[] blockArr = {b1, b2, b3};
        //定义一个变量用来存储要查找的值
        int number = 66;
        //调用方法,传递索引表、数组、要查找的值
        int index = blockSearch(blockArr, arr, number);
        System.out.println(index);

    }
    //利用分块原理,查询number在哪个块中
    public static int blockSearch(Block[] blockArr, int[] arr, int number){

        //1、确认number是在哪一块中
        int indexBlock = getIndex(blockArr, number);
        if(indexBlock == -1){
            //索引表中没有要查找的值
            return -1;
        }

        //2、获取这一块的起始索引和结束索引
        //Block b1 = new Block(21, 0, 5);
        //Block b2 = new Block(45, 6, 11);
        //Block b3 = new Block(73, 12, 17);
        int startIndex = blockArr[indexBlock].getStartIndex();
        int endIndex = blockArr[indexBlock].getEndIndex();

        //3、遍历这一块,获取这一块中的每一个元素
        for(int i = startIndex; i <= endIndex; i++){
            if(arr[i] == number){
                return i;
            }
        }
        return -1;
    }
    //定义一个方法。用来确定number在哪一个块中
    public static int getIndex(Block[] blockArr,int number){

        //从0索引开始遍历blockArr,如果number小于max,那么就表示number在这个块中
        for(int i = 0; i < blockArr.length; i++){
            //判断number是否小于索引表中的最大值
            //如果在,记录这个值的索引,并结束循环
            if(number <= blockArr[i].getMax()){
                return i;
            }
        }
        return -1;
    }

}
//JavaBean
class Block {
    private int max;
    private int startIndex;
    private int endIndex;


    public Block() {
    }

    public Block(int max, int startIndex, int endIndex) {
        this.max = max;
        this.startIndex = startIndex;
        this.endIndex = endIndex;
    }

    /**
     * 获取
     *
     * @return max
     */
    public int getMax() {
        return max;
    }

    /**
     * 设置
     *
     * @param max
     */
    public void setMax(int max) {
        this.max = max;
    }

    /**
     * 获取
     *
     * @return startIndex
     */
    public int getStartIndex() {
        return startIndex;
    }

    /**
     * 设置
     *
     * @param startIndex
     */
    public void setStartIndex(int startIndex) {
        this.startIndex = startIndex;
    }

    /**
     * 获取
     *
     * @return endIndex
     */
    public int getEndIndex() {
        return endIndex;
    }

    /**
     * 设置
     *
     * @param endIndex
     */
    public void setEndIndex(int endIndex) {
        this.endIndex = endIndex;
    }

    public String toString() {
        return "Block{max = " + max + ", startIndex = " + startIndex + ", endIndex = " + endIndex + "}";
    }
}

1.拓展1

请添加图片描述

6.哈希查找 ---->>拓展2

请添加图片描述

2.排序算法

1.冒泡排序(相邻-----先最大)

相邻的数据两两比较,小的放前面,大的放后面。
请添加图片描述
请添加图片描述

package mysort;

public class BubbleDemo1 {
    public static void main(String[] args) {
        // 冒泡排序
        // 核心:
        // 每次比较相邻的两个元素,如果前一个比后一个大,就交换
        // 每次比较完毕后,下一次的比较就会少一个元素
        // 需求:定义一个方法利用冒泡排序,对数组进行排序
        // 数组如下:{24, 69, 80, 57, 13}
        int[] arr = {24, 69, 80, 57, 13};
        bubbleSort(arr);
        printArr(arr);
    }
    public static void bubbleSort(int[] arr) {
        // 利用冒泡排序,对数组进行排序
        // 数组如下:{24, 69, 80, 57, 13}
        // 外层循环控制的是次数:arr.length - 1
        for (int i = 0; i < arr.length - 1; i++) {
            // 内存循环控制的是索引:arr.length - 1 - i
            for (int j = 0; j < arr.length - 1 - i; j++) {
                // 比较相邻的两个元素,如果前一个比后一个大,就交换
                if (arr[j] > arr[j + 1]) {
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
    }
    public static void printArr(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
    }
}

2.选择排序(0与后-----先最小)

从0索引开始,拿着每一个0索引上的元素跟后面的元素依次比较,小的放前面,大的放后面,以此类推。(数字pk)
请添加图片描述

package mysort;

public class SelectionDemo {
    public static void main(String[] args) {
        // 选择排序
        // 核心:
        // 每次循环找到最小的元素,放到前面
        // 需求:定义一个方法利用选择排序,将一个int数组中的数据从小到大排序
        // 数据如下:{24, 69, 80, 57, 13}
        int[] arr = {24, 69, 80, 57, 13};
        selectionSort(arr);
        printArr(arr);
    }
    public static void selectionSort(int[] arr) {
        // 利用选择排序,将一个int数组中的数据从小到大排序
        // 数据如下:{24, 69, 80, 57, 13}
        // 外层循环控制的是次数:arr.length - 1
        for (int i = 0; i < arr.length - 1; i++) {
            // 内存循环控制的是索引:i + 1
            for (int j = i + 1; j < arr.length; j++) {
                // 比较相邻的两个元素,如果前一个比后一个大,就交换
                if (arr[i] > arr[j]) {
                    int temp = arr[i];
                    arr[i] = arr[j];
                    arr[j] = temp;
                }
            }
        }
    }
    public static void printArr(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
    }
}

3.插入排序(分两派------无插有)

将0索引的元素到N索引的元素看作是有序的,把N+1索引的元素到最后一个当成是无序的。
遍历无序的数据,将遍历到的元素插入有序序列中适当的位置,如遇到相同数据,插在后面。
N的范围:0~最大索引

package mysort;

public class InsertDemo {
    public static void main(String[] args) {
        // 插入排序
        int[] arr = {3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48};

        //1.找到无序的那一组数据是从哪个索引开始的。    2
        int startIndex = -1;
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] > arr[i + 1]) {
                startIndex = i + 1;
                break;
            }
        }
        //2.遍历从startIndex开始的数据,依次插入到前面有序的序列中。
        for (int i = startIndex; i < arr.length; i++) {
            //问题:如何把arr[i]这个数据插入到前面的有序序列中?

            //记录要插入的数据的索引
            int j = i;
            while (j > 0 && arr[j] < arr[j - 1]) {
                //交换
                int temp = arr[j];
                arr[j] = arr[j - 1];
                arr[j - 1] = temp;
                j--;
            }
        }
        printArr(arr);
    }
    public static void printArr(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        System.out.println();
    }
}

4.递归算法(套娃)

指的是方法中调用方法本身的现象。
注意:递归一定要有出口(结束条件),否则就会出现内存溢出。
作用:大事化小,小事化了。

核心:

  • 找出口:什么时候不再调用方法。
  • 找规则:如何把大问题变成规模较小的问题。

请添加图片描述
请添加图片描述

一阶一阶的弹窗,往里加载方法,最后到结束条件把返回值返回给方法的调用者,然后方法一个一个出栈。

5.快速排序(0当原点,左右互换)

先移动end,再移动start。
请添加图片描述

package mysort;

public class QuickSortDemo {
    public static void main(String[] args) {
        int[] arr = {6, 1, 2, 7, 9, 3, 4, 5, 10, 8};
        quickSort(arr, 0, arr.length - 1);
        printArr(arr);
    }
    public static void quickSort(int[] arr, int left, int right) {
        if (left > right) {
            return;
        }
        int i = left;
        int j = right;
        int temp = arr[left];
        while (i != j) {
            while (arr[j] >= temp && i < j) {
                j--;
            }
            while (arr[i] <= temp && i < j) {
                i++;
            }
            if (i < j) {
                int t = arr[i];
                arr[i] = arr[j];
                arr[j] = t;
            }
        }
        arr[left] = arr[i];
        arr[i] = temp;
        quickSort(arr, left, i - 1);
        quickSort(arr, i + 1, right);
    }
    public static void printArr(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        System.out.println();
    }
}

相关文章:

  • Unity DOTS从入门到精通之 C# Job System
  • LeeCode题库第四十六题
  • 长上下文 GRPO
  • Core Speech Kit(基础语音服务)
  • Django与视图
  • 大整数加法(信息学奥赛一本通-1168)
  • 锂电池组的串数设计研究
  • QOJ9700 Ying’s Cup(拉格朗日插值优化卷积,背包,二项式反演)
  • c++ 嵌入汇编的方式实现int型自增
  • Javascript ajax
  • Compose笔记(八)--权限
  • 《Operating System Concepts》阅读笔记:p208-p227
  • 更新vscode ,将c++11更新到c++20
  • springboot旅游管理系统设计与实现(代码+数据库+LW)
  • openharmory-鸿蒙生态设备之间文件互传发现、接入认证和文件传输
  • 通义千问本地配置并实现微调
  • 手写Tomcat:实现基本功能
  • FastAPI Cookie 和 Header 参数完全指南:从基础到高级实战 [特殊字符]
  • MyBatis-Plus 注解大全
  • Java字符串拼接的底层原理与性能优化
  • 营销类wordpress主题/windows优化大师要会员
  • 广州网站建设推广服务/郑州seo使用教程
  • 东莞市招标网/郑州seo关键词优化公司
  • 网页设计介绍说明/北海百度seo
  • 电脑做网站服务器需要什么软件/百度关键词搜索排名帝搜软件
  • 网站变灰/推广普通话手抄报内容怎么写