向导

  • 1. 顺序查找,SequenceSearch
  • 2. 二分查找,BinarySearch


1. 顺序查找,SequenceSearch

算法思想:
  顺序查找也称为线形查找,属于无序查找算法。从数据结构线形表的一端开始,顺序扫描,依次将扫描到的结点关键字与给定值k相比较,若相等则表示查找成功;若扫描结束仍没有找到关键字等于k的结点,表示查找失败。。

代码实现:

public class SequenceSearch {

    public static void main(String[] args) {
        int[] dataArr = {3, 4, 5, 1, 6, 2};
        int index = sequenceSearch(dataArr, 5);
        System.out.println("index: " + index);
    }

    private static int sequenceSearch(int[] dataArr, int value) {
        for (int i = 0; i < dataArr.length; i++) {
            if (dataArr[i] == value) {
                return i;
            }
        }
        return -1;
    }
}

时间复杂度:

  1. 查找成功时的平均查找长度为:(假设每个数据元素的概率相等) ASL = 1/n(1+2+3+…+n) = (n+1)/2
  2. 当查找不成功时,需要n+1次比较,时间复杂度为O(n);
  3. 所以,顺序查找的时间复杂度为O(n)

2. 二分查找,BinarySearch

算法思想:
  有序的序列,每次都是以序列的中间位置的数来与待查找的关键字进行比较,每次缩小一半的查找范围,直到匹配成功。
  一个情景:将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。

算法说明:

  1. 优点:比较次数少,查找快,平均性能好
  2. 缺点:要求待查表有序,且插入删除困难
  3. 因此:适用于不常变化的、查找频繁的、有序的结构

代码实现:

import com.bigblue.algorithm.sort.QuickSort;
import java.util.Arrays;

public class BinarySearch {

    public static void main(String[] args) {
        int[] dataArr = {3, 4, 5, 1, 6, 2};
        QuickSort.quickSort(dataArr, 0, dataArr.length - 1);
        System.out.println(Arrays.toString(dataArr));

        int index1 = binarySearch(dataArr, 1);
        System.out.println("index1: " + index1);
        int index2 = recursionBinarySearch(dataArr, 0, dataArr.length - 1, 6);
        System.out.println("index2: " + index2);
    }

    /**
     * @Author: TheBigBlue
     * @Description: 循环方式
     **/
    public static int binarySearch(int[] dataArr, int value) {
        int left = 0;
        int right = dataArr.length - 1;
        //只定义一次
        int mid;
        while (left <= right) {
            mid = left + (right - left) / 2;
            if (dataArr[mid] == value) {
                return mid;
            } else if (dataArr[mid] > value) {
                right = mid - 1;
            } else {
                left = mid + 1;
            }
        }
        return -1;
    }

    /**
     * @Author: TheBigBlue
     * @Description: 递归方式
     **/
    public static int recursionBinarySearch(int[] dataArr, int left, int right, int value) {
        if(left > right){
            return -1;
        }
        int mid = left + (right - left) / 2;
        if(dataArr[mid] == value){
            return mid;
        }else if(dataArr[mid] > value) {
            return recursionBinarySearch(dataArr, left, mid - 1, value);
        }else {
            return recursionBinarySearch(dataArr, mid + 1, right, value);
        }
    }
}

时间复杂度:

  1. 最优:O(1),最差:O(logn),平均:O(logn)

空间复杂度:

  1. 循环方式:因为循环中无变量,所以为O(1)。
  2. 递归方式:递归的深度为O(logn),每个深度是常亮的,所以为O(logn)。