java常见算法篇【完整版】

14-常见算法

基本查找/顺序查找

  • 从0索引依次向后查找

二分查找/折半查找

  • 前提条件:数组中的数据必须是有序的
  • 核心逻辑:每次排除一半的查找范围
    请添加图片描述
    请添加图片描述
package io.xiaoduo.arithmetic;

public class Test1 {
    public static void main(String[] args) {
        int[] arr = {1, 12, 24, 35, 43, 52, 64, 75, 87, 99, 100};
        System.out.println(binarySearch(arr, 75)); // 7
    }

    // 二分查找
    private static int binarySearch(int[] arr, int num) {
        int min = 0;
        int max = arr.length - 1;
        while (true) {
            if (min > max) {
                return -1;
            }
            int mid = (min + max) / 2;
            if (arr[mid] > num) {
                max = mid - 1;
            } else if (arr[mid] < num) {
                min = mid + 1;
            } else {
                return mid;
            }
        }
    }
}

总结

  1. 二分查找的优势
    • 提高查找效率
  2. 二分查找的前提条件
    • 数据必须是有序的,如果数据是乱的,先排序再使用二分查找得到的索引没有实际意义,只能确定当前数字在数组中是否存在,因为排序之后的数字位置已经发生改变
  3. 二分查找的过程
    • min和max表示当前要查找的范围
    • mid是在min和max中间的
    • 如果要查找的元素在mid的左边,缩小范围时,min不变,max等于mid减一
    • 如果要查找的元素在mid的右边,缩小范围是,max不变,min等于mid加一

二分查找改进/插值查找

请添加图片描述

二分查找改进/斐波那契查找

请添加图片描述

分块查找

  • 核心思想:块内无序,块间有序

请添加图片描述

请添加图片描述

package io.xiaoduo.arithmetic;

public class Test2 {
    public static void main(String[] args) {
        // 分块查找
        int[] arr = {7, 10, 13, 19, 16, 20, 27, 22, 30, 40, 36, 43, 50, 48};
        // 第一步分块
        Block b1 = new Block(10, 0, 1);
        Block b2 = new Block(20, 2, 5);
        Block b3 = new Block(40, 6, 10);
        Block b4 = new Block(50, 11, 13);
        Block[] blockArr = {b1, b2, b3, b4};
        // 要查找的元素
        int num = 20;
        // 分块查找算法函数
        int index = blockSearch(blockArr, arr, num);
        System.out.println(index);
    }

    private static int blockSearch(Block[] blockArr, int[] arr, int num) {
        // 找到num属于哪个块
        int indexBlock = findIndexBlock(blockArr, num);
        // 超出块的范围
        if (indexBlock == -1) return -1;
        // 获取该块的开始和结束素引
        int startIndex = blockArr[indexBlock].getStartIndex();
        int endIndex = blockArr[indexBlock].getEndIndex();
        for (int i = startIndex; i <= endIndex; i++) {
            if (arr[i] == num) {
                return i;
            }
        }
        return -1;
    }

    private static int findIndexBlock(Block[] blockArr, int num) {
        for (int i = 0; i < blockArr.length; i++) {
            int max = blockArr[i].getMax();
            if (num <= max) {
                return i;
            }
        }
        return -1;
    }
}

class Block {
    public int max;
    public int startIndex;
    public int endIndex;

    public Block() {
    }

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

    public String toString() {
        return "Block{}";
    }

    /**
     * 获取
     *
     * @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;
    }
}

扩展的分块查找(无规律的数据)

请添加图片描述

扩展的分块查找(查找时添加数据),可以使用哈希查找

请添加图片描述

总结

  • 七种查找方式:基本查找,二分查找,差值查找,斐波那契查找,分块查找,哈希查找,树表查找

冒泡排序

  • 相邻的元素两两比较,大的放右边,小的放左边
package io.xiaoduo.arithmetic;

public class Test3 {
    public static void main(String[] args) {
        // 冒泡排序
        int[] arr = {2, 1, 6, 4, 7, 3, 8, 5, 9};
        mySort(arr);
        for (int i : arr) {
            System.out.print(i + " ");
        }
    }

    private static void mySort(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr.length - i - 1; j++) {
                if (arr[j] > arr[j + 1]) {
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
    }
}

选择排序

  • 从0索引开始,拿着每一个素引上的元素跟后面的元素依次比较,小的放前面,大的放后面,以此类推
package io.xiaoduo.arithmetic;

public class Test4 {
    public static void main(String[] args) {
        // 选择排序
        int[] arr = {2, 1, 6, 4, 7, 3, 8, 5, 9, 13, 10, 12, 11};
        mySort(arr);
        for (int i : arr) {
            System.out.print(i + " ");
        }
    }

    private static void mySort(int[] arr) {
        for (int i = 0; i < arr.length - 1; i++) {
            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;
                }
            }
        }
    }
}

插入排序

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

public class Test5 {
    public static void main(String[] args) {
        // 插入排序
        int[] arr = {2, 1, 6, 4, 7, 3, 8, 5, 9, 13, 10, 12, 11};
        mySort(arr);
    }

    private static void mySort(int[] arr) {
        int startIndex = -1;
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] > arr[i + 1]) {
                startIndex = i + 1;
                break;
            }
        }
        System.out.println(startIndex);
        for (int i = startIndex; i < arr.length; 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--;
            }
        }
        for (int i : arr) {
            System.out.print(i + " ");
        }
    }
}

递归算法

  • 指方法调用方法本身
  • 核心:找出口,找规律

快速排序

请添加图片描述

  • 开始索引找到比基准值大的和结束索引找到比基准值小的交换,先移动end再移动start

请添加图片描述

  • 开始索引和结束索引相同时将基准数停止位置交换,最后使用递归将基准值左边和右边的依次换算

请添加图片描述

  • 100万数据只排了149毫秒
package io.xiaoduo.arithmetic;

import java.util.Random;

public class Test6 {
    public static void main(String[] args) {
        // 快速排序
        // int[] arr = {7, 2, 1, 6, 4, 3, 8, 5, 9, 13, 10, 12, 11};
        int[] arr = new int[1000000];
        Random r = new Random();
        for (int i = 0; i < arr.length; i++) {
            arr[i] = r.nextInt();
        }
        long start = System.currentTimeMillis();
        quickSort(arr, 0, arr.length - 1);
        long end = System.currentTimeMillis();
        System.out.println(end - start);
        // for (int i : arr) {
        //     System.out.print(i + " ");
        // }
    }

    private static void quickSort(int[] arr, int i, int j) {
        // 开始索引
        int start = i;
        // 结束素引
        int end = j;
        if (start > end) {
            return;
        }
        // 基准数
        int baseNumber = arr[i];
        while (start != end) {
            while (true) {
                if (end <= start || arr[end] < baseNumber) {
                    break;
                }
                end--;
            }
            while (true) {
                if (end <= start || arr[start] > baseNumber) {
                    break;
                }
                start++;
            }
            int temp = arr[start];
            arr[start] = arr[end];
            arr[end] = temp;
        }
        int temp = arr[i];
        arr[i] = arr[start];
        arr[start] = temp;

        quickSort(arr, i, start - 1);
        quickSort(arr, start + 1, j);
    }
}

常见算法的API-Arrays

方法名说明
public static String toString(数组)把数组拼接成一个字符串
public static int binarySearch(数组,查找的元素)二分查找法查找元素
public static int[] copyOf(原数组,新数组长度)拷贝数组
public static int[] copyOfRange(原数组,起始索引,结束索引)范围拷贝数组
public static void fill(数组,元素)填充数组
public static void sort(数组)按照默认方式进行排序
public static void sort(数组,排序规则)按照指定规则排序

Lambda表达式

  • Lambda表达式是JDK8开始后的一种新语法形式

  • 例如 ( ) -> {}

  • Arrays.sort(arr, (Integer o1, Integer o2) -> {
        return o2 - o1;
    });
    
  • Lambda表达式可以用来简化匿名内部类的书写

  • Lambda表达式只能简化函数式接口的匿名内部类的写法

  • 函数式接口:有且仅有一个抽象方法的接口叫做函数式接口,接口上方可以加@FunctionalInterface注解

  • 和 js 的箭头函数写法很像,省略写法和箭头函数一样

其他

  • 字符串方法s1.compareTo(s2)返回int,-1表示s1小于s2, 遍历字符串ascall码表依次比较
  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
完整版Java网站,通常是指一个包含多个功能和模块的Java开发项目。这种网站通常具备以下特点: 1.用户界面:一个完整的Java网站会有一个用户友好的界面,以便用户能够轻松地访问和使用网站的各种功能。这个界面可能由HTML、CSS和JavaScript等技术开发而成,能够展示网站的内容和交互元素。 2.后端开发:完整的Java网站会包含后端开发,用于处理用户请求、数据存储和业务逻辑等功能。Java的后端开发常常使用JavaEE技术栈,如Servlet、JSP、JavaBeans、JDBC等,来构建强大的后台处理逻辑。 3.数据库支持:Java网站通常需要与数据库进行交互,以便存储和管理数据。常见Java数据库技术包括MySQL、PostgreSQL和Oracle等。Java的数据库访问技术,如JDBC和Hibernate,能够帮助开发人员在Java网站中有效地进行数据存取操作。 4.安全性:完整的Java网站通常会考虑用户数据和系统资源的安全。开发人员可以使用Java的安全技术,如HTTPS、加密算法和用户认证等,来保护网站的敏感信息和防止非法访问。 5.扩展性:Java网站需要具备一定的扩展性,以便能够适应不同规模和功能需求的变化。使用Java的模块化开发技术,如Spring和JavaEE容器,可以轻松地添加新的功能和模块,或者扩展现有功能和模块。 总之,一个完整版Java网站应该包含用户界面、后端开发、数据库支持、安全性和扩展性等方面的功能,以便提供用户友好的界面和实现丰富的功能需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值