1.查找
- 查找:在一些数据元素中,通过一定的方法找出与给定关键字相同的数据元素的过程;
- 列表查找(线性表查找):从列表中查找指定元素; 
  - 输入: 列表,待查找元素
- 输出:元素下标(未找到元素时一般返回None或-1)
 
- 内置列表查找函数:index of ()
2. 顺序查找(Linear Search)
顺序查找:也叫线性查找,从列表第一个元素开始,顺序进行搜索,直到找到元素或搜索到列表最后一个元素为止;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
/**
 * 线性查找/顺序查找
 *
 * @author wql
 * @date 2022/12/7 21:44
 */
public class LinearSearch {
    public static void main(String[] args) {
        List<String> asList = Arrays.asList("A", "AB", "AC");
        int index = handLinearSearch(asList, "AC");
        System.out.println("index = " + index);
    }
    
    /**
     * 顺序查找(线性查找)
     *
     * @param arr         待查找列表
     * @param targetValue 目标值
     * @return 目标值所处位置索引下标
     */
    public static int handLinearSearch(List<String> arr, String targetValue) {
        for (int i = 0; i < arr.size(); i++) {
            if (Objects.equals(targetValue, arr.get(i))) {
                return i;
            }
        }
        return -1;
    }
}

 如上图所示:分析算法时间复杂度三部曲:寻找规模n,是否存在循环减半过程,k层关于n的循环;从代码中,我们可以看出不存在循环减半和k层n循环的过程,问题规模是n,那么这个顺序查找的
 时间复杂度为: O(n)
3. 二分查找(Binary Search)
二分查找:又叫折半查找,从有序列表的初始候选区li[0:n] 开始,通过对待查找的值与候选区中间值的比较,可以是候选区减少一半;
案例:
 
 我们要从列表里面寻找3的位置,问题规模是n,目标值是3,那么在使用二分查找的时候,我们的关键是如何为维护候选区,候选区指的是目标值所在区域;假设初始的时候left是0,right是n-1,其实就是下标;
 那么我们求中间值就是left + right 之和,再除以2,也就是mid;
如上图所示,第一步中间值是5,5大于3,则要维护候选区,就是将right指针移动到mid-1的位置,如下图所示
 
 第二步:重新计算新的mid下标,此时0+3 除以2 等于1,那么mid光标在 2上面
 
 再比较2和3,发现2比3小,所以移动left,left的下一个位置等于mid位置+1
 
 第三步:left=2,right=3,那么2+3=5,除以2,等于2,所以mid等于left,也就是3上面
 
 最后一步:判断当mid值等于3时,输出mid值,也就是3的下标,如果left 大于right ,那么候选区没有值了,也就是找不到,返回-1
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
/**
 * 二分查找
 *
 * @author wql
 * @date 2022/12/7 22:01
 */
public class BinarySearch {
    public static void main(String[] args) {
        List<Integer> asList = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
        int index = handBinarySearch(asList, 3);
        System.out.println("index = " + index);
    }
    /**
     * 二分查找
     * <p>
     * 列表首先默认时排好序的
     *
     * @param arr         待查找列表
     * @param targetValue 目标值
     * @return 目标值所处位置索引下标
     */
    public static int handBinarySearch(List<Integer> arr, Integer targetValue) {
        //定义left right mid
        int left = 0;
        int right = arr.size() - 1;
        //当left<=right时,表示候选区有值
        while (left <= right) {
            //获取中间值的下标
            int mid = (left + right) / 2;
            if (Objects.equals(targetValue, arr.get(mid))) {
                return mid;
            } else if (arr.get(mid) > targetValue) {
                //如果中间值大于目标值,说明候选区在左侧
                right = mid - 1;
            } else if (arr.get(mid) < targetValue) {
                //如果中间值小于目标值,说明候选区在右侧
                left = mid + 1;
            }
        }
        return -1;
    }
}

 时间复杂度:O(logn)
4. 顺序查找和二分查找对比
二分查找效率远远大于 线性查找,那为啥jdk里面的 index of 函数不使用二分查找,因为使用二分查找的前提是列表必须是有序的;所以在不能保证列表有序的情况下,使用线性查找;因为排序也可能消耗大量的时间;














![[附源码]JAVA毕业设计学生公寓管理系统(系统+LW)](https://img-blog.csdnimg.cn/dc565216e6324f20bb60a48e1b24002e.png)




