1. 线性查找法(LinearSearch)

1.1 最简单的实现

  1. public class LinearSearch {
  2. //创建私有构造对象,不希望其他对象访问这个类
  3. private LinearSearch(){}
  4. //加上static不需要创建类也能访问
  5. public static int search(int data[] , int target){
  6. for (int i = 0; i< data.length ; i++){
  7. if (i == target)
  8. return i;
  9. }
  10. return -1;
  11. }
  12. public static void main(String[] args) {
  13. int [] data = {23,32,24,53,67,83,15,3};
  14. System.out.println(LinearSearch.search(data,24));
  15. System.out.println(LinearSearch.search(data,666));
  16. }
  17. }
  • 在这段代码中注意两点
    • 加上static不需要创建类也能访问,否则需要先创建类才能使用search方法
    • 创建私有构造对象,不希望其他对象访问这个类

1.2 使用泛型

  1. public class LinearSearch {
  2. //创建私有构造对象,不希望其他对象访问这个类
  3. private LinearSearch(){}
  4. //加上static不需要创建类也能访问
  5. public static <E> int search(E data[] , E target){
  6. for (int i = 0; i< data.length ; i++){
  7. if (data[i].equals(target) )
  8. return i;
  9. }
  10. return -1;
  11. }
  12. public static void main(String[] args) {
  13. Integer [] data = {23,32,24,53,67,83,15,3};
  14. System.out.println(LinearSearch.search(data,24));
  15. System.out.println(LinearSearch.search(data,666));
  16. }
  17. }
  • 注意:
    • 在泛型类中不能使用基本数据类型(int,double,long….),只能使用对应的Integer,Double,Long….,因此data的定义也要从int->Integer
    • int : 表示传入的参数是一个泛型,返回的是一个int值

1.3 使用自定义类测试时

  • 注意这里的equals比较的只是两个类的地址,因此需要在类中重写equals方法

    image.png

  • 比如现在要比较Student类中的内容,重写equals方法时要注意,因为该方法是Object的,因此当检测到传入的参数是Object类时才可以重写

    image.png

1.4 循环不变量

2-6 循环不变量【一手微信itit11223344】.mp4_20210808_131624450.jpg

1.5 复杂度分析

  • 什么是算法复杂度

2-7 简单的复杂度分析【一手微信itit11223344】.mp4_20210808_133756733.jpg

  • 常见的几种算法复杂度

    • O(n)
    • O(n2):冒泡算法
    • O(logn):数字n的二进制位数

      image.png

    • O(√n):

    • O(2n):求长度为n的二进制数字
    • O(n!):求长度为n的数组的所有排列
    • O(1):判断n是否为偶数
  • 大小比较:

image.png

2. 基础排序方法(SelectionSort)

2.1 选择排序法

2.1.1 基础实现:

  • 简单来说就是,(从小到大派的情况下)每次都选择数组里面最小的一个数,然后交换位置

image.png

  1. public class SelectionSort {
  2. private SelectionSort(){}
  3. public static void sort(int arr[]){
  4. for (int i=0 ;i<arr.length;i++){
  5. int minIndex = i;
  6. for (int j=i; j<arr.length;j++){
  7. if (arr[j]<arr[minIndex]){
  8. minIndex = j;
  9. }
  10. }
  11. swap(arr,i,minIndex);
  12. }
  13. }
  14. private static void swap(int[] arr, int i, int minIndex) {
  15. int t = arr[i];
  16. arr[i] = arr[minIndex];
  17. arr[minIndex] = t;
  18. }
  19. public static void main(String[] args) {
  20. int arr[] = {34,32,3,4,43,23,15,5};
  21. SelectionSort.sort(arr);
  22. for (int i : arr) {
  23. System.out.print(i+" ");
  24. }
  25. }
  26. }

2.1.2 使用泛型

  • 使用泛型要用到比较时,使用 <E extends Compareable> , 然后后面的比较函数使用 compareTo() ,当返回的值等于0时说明相等,小于0时就是前面比后面小,大于0就是前面比后面大

  • ```java public class SelectionSort {

    private SelectionSort(){}

    public static void sort(E arr[]){

    1. for (int i=0 ;i<arr.length;i++){
    2. int minIndex = i;
    3. for (int j=i; j<arr.length;j++){
    4. if (arr[j].compareTo(arr[minIndex])<0){
    5. minIndex = j;
    6. }
    7. }
    8. swap(arr,i,minIndex);
    9. }

    }

    private static void swap(E[] arr, int i, int minIndex) {

    1. E t = arr[i];
    2. arr[i] = arr[minIndex];
    3. arr[minIndex] = t;

    }

    public static void main(String[] args) {

    1. Integer arr[] = {34,32,3,4,43,23,15,5};
    2. SelectionSort.sort(arr);
    3. for (int i : arr) {
    4. System.out.print(i+" ");
    5. }

    }

}

  1. <a name="IVAOa"></a>
  2. ### 2.1.3 复杂度分析
  3. ![1-5 选择排序法的复杂度分析【一手微信itit11223344】.mp4_20210810_235015696.jpg](https://cdn.nlark.com/yuque/0/2021/jpeg/21552184/1628612971950-537983b7-4c7d-46c5-8446-38cda56b127b.jpeg#height=417&id=kqXDi&margin=%5Bobject%20Object%5D&name=1-5%20%E9%80%89%E6%8B%A9%E6%8E%92%E5%BA%8F%E6%B3%95%E7%9A%84%E5%A4%8D%E6%9D%82%E5%BA%A6%E5%88%86%E6%9E%90%E3%80%90%E4%B8%80%E6%89%8B%E5%BE%AE%E4%BF%A1itit11223344%E3%80%91.mp4_20210810_235015696.jpg&originHeight=1080&originWidth=1728&originalType=binary&ratio=1&size=94484&status=done&style=none&width=667)<br />测试结果:<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/21552184/1628612844733-b147b5f1-41f4-42e9-a477-246559b3c011.png#height=94&id=mTV4g&margin=%5Bobject%20Object%5D&name=image.png&originHeight=94&originWidth=529&originalType=binary&ratio=1&size=39395&status=done&style=none&width=529)
  4. - 当n相差10倍时,时间复杂度却差了100倍,这就是 复杂度=n2的意义
  5. <a name="3IVL7"></a>
  6. ## 2.2 插入排序法
  7. <a name="JCmVJ"></a>
  8. ### 2.2.1 实现一个插入算法
  9. - 插入算法的原理
  10. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/21552184/1631196158591-5762797b-3fb2-48c7-b98c-4454e1c670eb.png#height=441&id=qS2rQ&margin=%5Bobject%20Object%5D&name=image.png&originHeight=441&originWidth=721&originalType=binary&ratio=1&size=38935&status=done&style=none&width=721)
  11. - 过程:i的位置一格格移,然后j开始和i的位置一样(j=i)跟前面的数去一个个比较,遇到比他大的那就把他后移,直到遇到一个比他小的数的时候停止(前面已经排好了)
  12. ```java
  13. public static <E extends Comparable> void sort(E[] arr){
  14. for (int i = 0 ; i < arr.length ; i++){
  15. //之所以要j-1,是因 为要保证他前面那个位置是有元素的
  16. for (int j = i ; j-1 >=0 ; j--){
  17. if (arr[j].compareTo(arr[j-1]) < 0){
  18. swap(arr,j,j-1);
  19. }
  20. else break;
  21. }
  22. //可以简写成下面这样
  23. //for (int j = i ; j-1 >= 0 && arr[j].compareTo(arr[j-1]) < 0; j--){
  24. // swap(arr,j,j-1);
  25. //}
  26. }
  27. }

2.2.2 插入排序优化

  • 优化图示:

image.png
image.png
image.png
image.png

  • 过程:先把当前位置的数提出来,然后开始拿这个数和前面的数依次去比较,如果前面的数要大,那就直接把后面的数覆盖掉,直到前面的数比你小;然后i++,再重复上述操作

2.2.3 插入排序法的重要特性

  • 对于有序数组,插入排序法复杂度是O(n),但复杂度要看整体,所以还是O(n^2)
  • 但是选择排序法永远是O(n^2)
  • 因此对于基本上有序的数组,插入排序将成为O(n)的算法

image.png