• 查找(顺序查找、折半查找、分块查找)


    1、顺序查找

    (1)顺序查找数组中的元素是否存在

    public class Test {
        public boolean findNumberInArray(int[][] matrix, int target) {
            boolean result = false;
            for (int i = 0; i < matrix.length; i++) {
                for (int j = 0; j < matrix[0].length; j++) {
                    if (matrix[i][j] == target) {
                        result = true;
                        break;
                    }
                }
            }
            return result;
        }
    
        public static void main(String[] args) {
            int[][] matrix = {
                    {1, 4, 7, 11, 15},
                    {2, 5, 8, 12, 19},
                    {3, 6, 9, 16, 22},
                    {10, 13, 14, 17, 24},
                    {18, 21, 23, 26, 30}};
            Test test=new Test();
            boolean b=test.findNumberInArray(matrix,2);
            System.out.println(b);
        }
    }

    类似于穷举法,遍历出每一种可能,然后找出需要的结果

    测试结果:

    true

    (2)时间复杂度与空间复杂度

    时间复杂度:O(n2)

    空间复杂度:O(1)

    (3)适用场景

    顺序存储或链接存储的线性表 

    2、折半查找

    (1)查找流程

    第一次:low=1,high=11(不是数组下标,仅代表元素顺序),计算的middle的值是6

    第二次:因为要查找的数据的值要小于middle所对应的值,因此,要移动high到middle下标减一的位置

    第三次:middle为3,查找的数据大于middle中的数据,因此要移动low到middle下标加一的位置

    第四次:下标加1为4,也就是说low=4,high=5,计算middle的下标为4,此时的数据就是要查找的数据

    (2)代码

    public class Test {
        public static int binarySearch(int[] array,int key){
            int low = 0;
            int high = array.length - 1;
            if(low>high||key>array[high]||key<array[low]){
                return -1;
            }
            while(low<=high){
                int mid = low+ (high - low)/2;
                if(key==array[mid]){
                    return mid;
                }else if (key>array[mid]){
                    low = mid+1; //mid所对应的的值比key小,移动low
                }else {
                    high = mid-1;  //mid所对应的的值比key大,移动high
                }
            }
            return -1;
        }
        public static void main(String[] args) {
            int[] arr = new int[]{15,66,48,9,54,11,87,100,40,8,9,7,12,13};
            int key = 11;
            Arrays.sort(arr);
            System.out.println(Arrays.toString(arr));
            System.out.println(key+"元素的索引"+binarySearch(arr,key));
        }
    }

    测试结果:

    true

    先排除一定错误的情况,第一:low索引大于high索引,第二:要查找的数据的值比最小值小或者比最大值大

    然后是low<high的情况:只要是low<high就一直执行死循环:令mid = low+ (high - low)/2,如果mid索引所对应的数据的值等于要查找的值就返回对应的值;如果要查找的数据的值大于mid索引所对应的数据,那么就让low=mid+1,否则,让high = mid-1

    (3)总结

    时间复杂度:O(log n)

    空间复杂度:O(1)

    要求:

    顺序结构

    元素有序:如果数据是无序的,可以尝试先将数据进行排序,变为有序后就可以使用二分查找了

    3、折半查找的递归写法

    (1)递归实现者半查找

    public class Test {
        public static int binarySearch(int[] array,int left,int right,int findVal){
            int mid = (right + left)/2;
            int midVal=array[mid];
            if (left>right){
                return -1;
            }
            if(findVal>midVal){
                return binarySearch(array,mid+1,right,findVal);
            }else if(findVal<midVal){
                return binarySearch(array,left,mid-1,findVal);
            }else {
                return mid;
            }
        }
        public static void main(String[] args) {
            int[] arr = new int[]{15,66,48,9,54,11,87,100,40,8,9,7,12,13};
            Arrays.sort(arr);
            System.out.println(Arrays.toString(arr));
            System.out.println("元素的索引"+binarySearch(arr,0,arr.length-1,999));
        }
    }

    测试查找元素存在的情况:

    [7, 8, 9, 9, 11, 12, 13, 15, 40, 48, 54, 66, 87, 100]
    元素的索引2

    测试元素不存在的情况:

    [7, 8, 9, 9, 11, 12, 13, 15, 40, 48, 54, 66, 87, 100]
    元素的索引-1

    (2)总结

      一个函数自身调用自身就是递归,要想使用递归需要满足以下三个条件:需要解决的问题可以转换为一个或多个子问题来求解,而这些子问题的解法与原问题完全相同只是在数量和规模上不同;递归的次数必须是有限的;必须有递归结束的终止条件

    4、分块查找

      分块查找又称为索引顺序查找,是一种性能介于顺序查找和折半查找之同的一种查找方法。需要将块内的数据分为若干个子块,块内的元素可以无序,但是块之间是有序的(一个块内的最大关键字小于其后一个块的所有关键字)。还需要建立一张索引表,索引的每个元素含有各块的最大关键字和每块中的第一个元素。查找的时候需要用顺序查找或折半查找确定记录所在的块,然后是在块内顺序查找。

    每个人都会有一段异常艰难的时光 。 生活的压力 , 工作的失意 , 学业的压力。 爱的惶惶不可终日。 挺过来的 ,人生就会豁然开朗。 挺不过来的 ,时间也会教你 ,怎么与它们握手言和 ,所以不必害怕的。 ——杨绛
  • 相关阅读:
    HDU 6166
    codeforces 798D Mike and distribution
    Codeforces Round #409 (Div. 2) D Volatile Kite
    Codeforces Round #409 (Div. 2) C Voltage Keepsake(二分)
    HDU 4609 3-idiots(FFT计数)
    LightOJ 1236 Pairs Forming LCM(算术基本定理)
    HDU 1540 Tunnel Warfare(线段树,单点更新,区间查询)
    创建最简单的Struts2项目
    java自定义拦截器
    java拦截器和过滤器的区别
  • 原文地址:https://www.cnblogs.com/zhai1997/p/13669866.html
Copyright © 2020-2023  润新知