演算法篇——二分查詢法(折半查詢法)
阿新 • • 發佈:2018-12-14
二分查詢法(折半查詢法):查詢陣列中是否包含指定元素。如果包含指定元素,則返回指定元素的index(從0開始);如果不包含指定元素,則返回-1;
前提:陣列中的元素必須是有序的。
原理:將被查詢的陣列分為三部分,依次是中值前、中值、中值後,將指定元素和陣列的中值進行比較,如果指定元素小於中值則在(中值前)中找,如果指定元素大於中值則在(中值後)中找,如果指定元素等於中值則直接返回。依次查詢後,如果不包含指定元素,則返回-1;
注:中值即陣列中間位置的值。
原生方法:Arrays.sort(a);:對a陣列進行升序排序。
Arrays.binarySearch(a,b);:使用二分法查詢a陣列中是否包含b這個元素。
自定義方法:
兩種方式:迴圈實現和遞迴實現
/** * 迴圈實現 * 二分查詢法(折半查詢法):查詢陣列中是否包含指定元素。 * 前提:陣列中的元素必須是有序的。 * Arrays.sort(a);:對a陣列進行升序排序。 * Arrays.binarySearch(a,b);:使用二分法查詢a陣列中是否包含b這個元素。 * * @param arr 被查詢的陣列 * @param key 指定元素 * @return 如果包含指定元素,則返回指定元素的index(從0開始);如果不包含指定元素,則返回-1; */ public static int binarySearch(int[] arr, int key) { int min = 0; int max = arr.length - 1; while (min <= max) { int mid = (min + max) >> 1;//(min + max)/2 if (arr[mid] > key) { max = mid - 1; } else if (arr[mid] < key) { min = mid + 1; } else { return mid; } } return -1; } /** * 遞迴實現 * 二分查詢法(折半查詢法):查詢陣列中是否包含指定元素。 * 前提:陣列中的元素必須是有序的。 * Arrays.sort(a);:對a陣列進行升序排序。 * Arrays.binarySearch(a,b);:使用二分法查詢a陣列中是否包含b這個元素。 * * @param arr 被查詢的陣列 * @param key 指定元素 * @return 如果包含指定元素,則返回指定元素的index(從0開始);如果不包含指定元素,則返回-1; */ public static int binarySearch(int[] arr, int key, int startIndex, int endIndex) { if (startIndex > endIndex || startIndex < 0 || endIndex > arr.length - 1) { return -1; } int midIndex = (startIndex + endIndex) >> 1;//(startIndex + endIndex)/2 if (arr[midIndex] > key) { return binarySearch(arr, key, startIndex, midIndex - 1); } else if (arr[midIndex] < key) { return binarySearch(arr, key, midIndex + 1, endIndex); } else { return midIndex; } }
驗證:
//驗證自定義的二分查詢法 int[] a = {}; int[] b = {1, 2, 3, 4, 5, 6, 7, 8, 9}; int[] c = {1, 4, 6, 7, 8, 3, -2}; //迴圈實現 int circulate1 = binarySearch(a, 0); int circulate2 = binarySearch(b, 5); int circulate3 = binarySearch(c, -2); Arrays.sort(c); int circulate4 = binarySearch(c, -2); LogUtil.e("++++++++++++++++", circulate1 + ""); //-1 LogUtil.e("++++++++++++++++", circulate2 + ""); //4 LogUtil.e("++++++++++++++++", circulate3 + ""); //-1 LogUtil.e("++++++++++++++++", circulate4 + ""); //0 //遞迴實現 int recursion1 = binarySearch(a, 0, 0, a.length - 1); int recursion2 = binarySearch(b, 5, 0, b.length - 1); int recursion3 = binarySearch(c, -2, 0, c.length - 1); LogUtil.e("++++++++++++++++", recursion1 + ""); //-1 LogUtil.e("++++++++++++++++", recursion2 + ""); //4 LogUtil.e("++++++++++++++++", recursion3 + ""); //0