查找(順序查找、折半查找、分塊查找)


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、分塊查找

  分塊查找又稱為索引順序查找,是一種性能介於順序查找和折半查找之同的一種查找方法。需要將塊內的數據分為若干個子塊,塊內的元素可以無序,但是塊之間是有序的(一個塊內的最大關鍵字小於其后一個塊的所有關鍵字)。還需要建立一張索引表,索引的每個元素含有各塊的最大關鍵字和每塊中的第一個元素。查找的時候需要用順序查找或折半查找確定記錄所在的塊,然后是在塊內順序查找。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM