目录
可以是有序的,也可以是无序的。
- public class SeqSearch {
- public static void main(String[] args) {
- int[] arr = new int[]{1, 9, 11, -1, 34, 89};
- int res = seqSearch(arr, 34);
- }
-
- public static int seqSearch(int[] arr, int n) {
- for (int i = 0; i < arr.length; i++) {
- if (arr[i] == n) {
- return i;
- }
- }
- return -1;
- }
- }
也叫折半查找,数组必须有序。
- public class BinarySearch {
- public static void main(String[] args) {
- int[] arr = new int[]{2, 2, 4, 4, 5};
- // int res = binarySearch(arr, 6);
- List list = binarySearchPlus(arr, 6);
- }
-
- public static int binarySearch(int[] arr, int n) {
- int l = 0;
- int r = arr.length - 1;
- while (l <= r) {
- int m = (l + r) / 2;
- if (n < arr[m]) {
- r = m - 1;
- } else if (n > arr[m]) {
- l = m + 1;
- } else if (n == arr[m]) {
- return m;
- } else {
- return -1;
- }
- }
- return -1;
- }
-
- public static ArrayList binarySearchPlus(int[] arr, int n) {
- int l = 0;
- int r = arr.length - 1;
- while (l <= r) {
- int m = (l + r) / 2;
- if (n < arr[m]) {
- r = m - 1;
- } else if (n > arr[m]) {
- l = m + 1;
- } else if (n == arr[m]) {
- ArrayList
list = new ArrayList<>(); - list.add(m);
- for (int i = m - 1; i >= 0 && n == arr[i]; i++) {
- list.add(i);
- }
- for (int i = m + 1; i < arr.length && n == arr[i]; i++) {
- list.add(i);
- }
- Collections.sort(list);
- return list;
- } else {
- return null;
- }
- }
- return null;
- }
- }
在不使用递归的方式下进行二分查找
- // 非递归实现的二分查找
- public static int binarySearch(int[] arr, int target) {
- if (arr.length == 0 || target < arr[0] || target > arr[arr.length - 1]) {
- return -1;
- }
- int left = 0;
- int right = arr.length - 1;
- while (left <= right) {
- int mid = (left + right) / 2;
- if (target == arr[mid]) {
- return mid;
- } else if (target < arr[mid]) {
- right = mid - 1;
- } else {
- left = mid + 1;
- }
- }
- return -1;
- }
二分查找:

插值查找:
![mid=low+\frac{key-a[low]}{a[high]-a[low]}(high-low)](https://1000bd.com/contentImg/2024/03/12/141304090.png)
适用于数据连续的数组,通过黄金分割点的算法。
- public class InsertSearch {
- public static void main(String[] args) {
- int[] arr = new int[100];
- for (int i = 0; i < arr.length; i++) {
- arr[i] = i + 1;
- }
- int res = insertSearch(arr, 50);
- }
-
- public static int insertSearch(int[] arr, int key) { // 也要求数组有序
- int high = arr.length - 1;
- int low = 0;
- while (low <= high) {
- int mid = low + (high - low) * (key - arr[low]) / (arr[high] - arr[low]);
- if (mid < 0) { // 左越界
- if (key < arr[0]) {
- return -1;
- }
- mid = 0;
- }
- if (mid > arr.length - 1) { // 右越界
- if (key > arr[arr.length - 1]) {
- return -1;
- }
- mid = arr.length - 1;
- }
- if (key > arr[mid]) {
- low = mid + 1;
- } else if (key < arr[mid]) {
- high = mid - 1;
- } else if (key == arr[mid]) {
- return mid;
- } else {
- return -1;
- }
- }
- return -1;
- }
- }
也叫黄金分割点查找法,也适用于连续的数组。
- public class FibonacciSearch {
- public static int maxSize = 20;
-
- public static void main(String[] args) {
- int[] arr = new int[]{1, 8, 10, 89, 1000, 1024};
- int res = fibSearch(arr, 1025);
- }
-
- // 获得一个斐波那契数列
- public static int[] fib() {
- int[] f = new int[maxSize];
- f[0] = f[1] = 1;
- for (int i = 2; i < maxSize; i++) {
- f[i] = f[i - 1] + f[i - 2];
- }
- return f;
- }
-
- public static int fibSearch(int[] arr, int key) {
- int low = 0;
- int high = arr.length - 1;
- int k = 0;
- int mid;
- int[] f = fib();
- // 获得新数组的大小,新数组的大小大于等于旧数组,并且符合斐波那契数列
- while (f[k] - 1 < high) { // 斐波那契数列 大于等于 最大下标
- k++;
- } // 把原数组扩容成斐波那契大小的数组,然后再找黄金分割点
- int[] temp = Arrays.copyOf(arr, f[k]); // new一个f[k]这么大的数组,并把arr拷贝进去
- for (int i = high + 1; i < temp.length; i++) {
- temp[i] = arr[high];
- }
- while (low <= high) {
- mid = low + f[k - 1] - 1; // 获得黄金分割点
- if (key < temp[mid]) {
- high = mid - 1;
- k--;
- } else if (key > temp[mid]) {
- low = mid + 1;
- /**
- * 全部元素=前面元素+后面元素
- * f[k]=f[k-1]+f[k-2]
- */
- k -= 2;
- } else {
- if (mid <= high) {
- return mid;
- } else {
- return high;
- }
- }
- }
- return -1;
- }
- }