• 数据结构和算法——查找算法


    目录

    线性查找法

    二分查找法

    插值查找法

    斐波那契查找法


    线性查找

    可以是有序的,也可以是无序的。

    1. public class SeqSearch {
    2. public static void main(String[] args) {
    3. int[] arr = new int[]{1, 9, 11, -1, 34, 89};
    4. int res = seqSearch(arr, 34);
    5. }
    6. public static int seqSearch(int[] arr, int n) {
    7. for (int i = 0; i < arr.length; i++) {
    8. if (arr[i] == n) {
    9. return i;
    10. }
    11. }
    12. return -1;
    13. }
    14. }

    二分查找法

    也叫折半查找,数组必须有序。

    1. public class BinarySearch {
    2. public static void main(String[] args) {
    3. int[] arr = new int[]{2, 2, 4, 4, 5};
    4. // int res = binarySearch(arr, 6);
    5. List list = binarySearchPlus(arr, 6);
    6. }
    7. public static int binarySearch(int[] arr, int n) {
    8. int l = 0;
    9. int r = arr.length - 1;
    10. while (l <= r) {
    11. int m = (l + r) / 2;
    12. if (n < arr[m]) {
    13. r = m - 1;
    14. } else if (n > arr[m]) {
    15. l = m + 1;
    16. } else if (n == arr[m]) {
    17. return m;
    18. } else {
    19. return -1;
    20. }
    21. }
    22. return -1;
    23. }
    24. public static ArrayList binarySearchPlus(int[] arr, int n) {
    25. int l = 0;
    26. int r = arr.length - 1;
    27. while (l <= r) {
    28. int m = (l + r) / 2;
    29. if (n < arr[m]) {
    30. r = m - 1;
    31. } else if (n > arr[m]) {
    32. l = m + 1;
    33. } else if (n == arr[m]) {
    34. ArrayList list = new ArrayList<>();
    35. list.add(m);
    36. for (int i = m - 1; i >= 0 && n == arr[i]; i++) {
    37. list.add(i);
    38. }
    39. for (int i = m + 1; i < arr.length && n == arr[i]; i++) {
    40. list.add(i);
    41. }
    42. Collections.sort(list);
    43. return list;
    44. } else {
    45. return null;
    46. }
    47. }
    48. return null;
    49. }
    50. }

    在不使用递归的方式下进行二分查找

    1. // 非递归实现的二分查找
    2. public static int binarySearch(int[] arr, int target) {
    3. if (arr.length == 0 || target < arr[0] || target > arr[arr.length - 1]) {
    4. return -1;
    5. }
    6. int left = 0;
    7. int right = arr.length - 1;
    8. while (left <= right) {
    9. int mid = (left + right) / 2;
    10. if (target == arr[mid]) {
    11. return mid;
    12. } else if (target < arr[mid]) {
    13. right = mid - 1;
    14. } else {
    15. left = mid + 1;
    16. }
    17. }
    18. return -1;
    19. }

    插值查找法

    二分查找:

    mid=\frac{low+high}{2}=low+\frac{1}{2}(high-low)

    插值查找:

    mid=low+\frac{key-a[low]}{a[high]-a[low]}(high-low)

    适用于数据连续的数组,通过黄金分割点的算法。

    1. public class InsertSearch {
    2. public static void main(String[] args) {
    3. int[] arr = new int[100];
    4. for (int i = 0; i < arr.length; i++) {
    5. arr[i] = i + 1;
    6. }
    7. int res = insertSearch(arr, 50);
    8. }
    9. public static int insertSearch(int[] arr, int key) { // 也要求数组有序
    10. int high = arr.length - 1;
    11. int low = 0;
    12. while (low <= high) {
    13. int mid = low + (high - low) * (key - arr[low]) / (arr[high] - arr[low]);
    14. if (mid < 0) { // 左越界
    15. if (key < arr[0]) {
    16. return -1;
    17. }
    18. mid = 0;
    19. }
    20. if (mid > arr.length - 1) { // 右越界
    21. if (key > arr[arr.length - 1]) {
    22. return -1;
    23. }
    24. mid = arr.length - 1;
    25. }
    26. if (key > arr[mid]) {
    27. low = mid + 1;
    28. } else if (key < arr[mid]) {
    29. high = mid - 1;
    30. } else if (key == arr[mid]) {
    31. return mid;
    32. } else {
    33. return -1;
    34. }
    35. }
    36. return -1;
    37. }
    38. }

    斐波那契查找

    也叫黄金分割点查找法,也适用于连续的数组。

    1. public class FibonacciSearch {
    2. public static int maxSize = 20;
    3. public static void main(String[] args) {
    4. int[] arr = new int[]{1, 8, 10, 89, 1000, 1024};
    5. int res = fibSearch(arr, 1025);
    6. }
    7. // 获得一个斐波那契数列
    8. public static int[] fib() {
    9. int[] f = new int[maxSize];
    10. f[0] = f[1] = 1;
    11. for (int i = 2; i < maxSize; i++) {
    12. f[i] = f[i - 1] + f[i - 2];
    13. }
    14. return f;
    15. }
    16. public static int fibSearch(int[] arr, int key) {
    17. int low = 0;
    18. int high = arr.length - 1;
    19. int k = 0;
    20. int mid;
    21. int[] f = fib();
    22. // 获得新数组的大小,新数组的大小大于等于旧数组,并且符合斐波那契数列
    23. while (f[k] - 1 < high) { // 斐波那契数列 大于等于 最大下标
    24. k++;
    25. } // 把原数组扩容成斐波那契大小的数组,然后再找黄金分割点
    26. int[] temp = Arrays.copyOf(arr, f[k]); // new一个f[k]这么大的数组,并把arr拷贝进去
    27. for (int i = high + 1; i < temp.length; i++) {
    28. temp[i] = arr[high];
    29. }
    30. while (low <= high) {
    31. mid = low + f[k - 1] - 1; // 获得黄金分割点
    32. if (key < temp[mid]) {
    33. high = mid - 1;
    34. k--;
    35. } else if (key > temp[mid]) {
    36. low = mid + 1;
    37. /**
    38. * 全部元素=前面元素+后面元素
    39. * f[k]=f[k-1]+f[k-2]
    40. */
    41. k -= 2;
    42. } else {
    43. if (mid <= high) {
    44. return mid;
    45. } else {
    46. return high;
    47. }
    48. }
    49. }
    50. return -1;
    51. }
    52. }

  • 相关阅读:
    【网站放大镜效果】两种方式实现
    告别杂音,从 AI 音频降噪开始
    PHP:回退(Backed)枚举
    esp32-S3 + visual studio code 开发环境搭建
    深入探讨栈数据结构:定义、特性和应用
    MySQL存储引擎介绍
    4 搜索插入位置
    EMQX Cloud全托管的 MQTT 消息云服务
    融云「百幄」之数字人,升级交互体验的「新同事」
    golang设计模式——设计原则
  • 原文地址:https://blog.csdn.net/m0_58961367/article/details/133817103