参考教材:《算法设计与应用》 汪荣贵 杨娟 薛丽霞 机械工业出版社

第7章 查找算法设计与分析

查找,顾名思义,是指在大量的数据元素中通过一定的方法寻找某个特定的元素。
以查找策略为标准,可分为二分查找、斐波那契查找、索引表查找、哈希表查找、广度深度优先查找、红黑树查找、B树查找等。
以查找形式为标准,可将排序算法分为如下4种基本类型,即静态表查找算法、散列表查找算法、搜索树查找算法和特殊树查找算法。

7.1 静态表查找算法

静态查找表就是使用静态的表结构进行查找,在查找的过程中表结构始终保持不变。

7.1.1 顺序表查找

  1. // 顺序表查找算法
  2. // 输入:数组A,数组元素个数n,待比较关键字的值K
  3. // 输出:查找的结果
  4. #include <iostream>
  5. using namespace std;
  6. int Sequece_Search(int A[], int n, int K) {
  7. for (int i = 0; i < n; i++) {
  8. if (A[i] == K) return i;
  9. }
  10. return -1;
  11. }
  12. int main() {
  13. int A[] = { 1,2,3,4,5 };
  14. int res = Sequece_Search(A, 5, 3);
  15. cout << res;
  16. return 0;
  17. }

7.1.2 有序表查找

对于以数组方式存储的数据,如果已按其关键字值的大小顺序排好,则称为有序数组或有序表

1、折半查找

  1. // 折半查找算法
  2. #include <iostream>
  3. using namespace std;
  4. int bin_search(int a[], int low, int high, int key) {
  5. if (low > high)
  6. return -1;
  7. else {
  8. int mid = (low + high) / 2;
  9. if (a[mid] == key) return mid;
  10. else if (key < a[mid]) {
  11. return bin_search(a, low, mid - 1, key);
  12. }
  13. else {
  14. return bin_search(a, mid + 1, high, key);
  15. }
  16. }
  17. }
  18. int main() {
  19. int A[] = { 1,2,3,4,5 };
  20. int res = bin_search(A, 0, 5, 3);
  21. cout << res;
  22. return 0;
  23. }

3、斐波那契查找

通过斐波那契数列来构造类似于堆查找

  1. // 斐波那契查找算法
  2. // 输入:数组a,数组长度,待查找关键字key
  3. // 输出:返回查找结果,若查找成功,返回key在数组中的下标,否则返回-1
  4. #define MAXSIZE 13
  5. #include <iostream>
  6. using namespace std;
  7. // 非递归算法构造斐波那契数列
  8. void Fibonacci(int* f) {
  9. f[0] = 0;
  10. f[1] = 1;
  11. for (int i = 2; i < MAXSIZE; i++) {
  12. f[i] = f[i - 1] + f[i - 2];
  13. }
  14. }
  15. int Fibonacci_Search(int* a, int n, int key) {
  16. int low, high, mid;
  17. low = 0;
  18. high = n - 1;
  19. int k = 0;
  20. int F[MAXSIZE];
  21. Fibonacci(F);
  22. //查找n在斐波那契数列中的位置
  23. while (n > F[k] - 1) {
  24. k++;
  25. }
  26. //查找n在斐波那契数列中的位置
  27. while (n > F[k] - 1) {
  28. k++;
  29. }
  30. //将a的元素扩展到“某斐波那契数-1”.即F[k]-1
  31. for (int i = n; i < F[k] - 1; i++) {
  32. a[i] = a[high];
  33. }
  34. //当键值小于a[mid]时,就在[low,F[k-1]-1]范围内查找;当键值大于a[mid]时,就在[F[k-2]-1,high]范围内查找
  35. while (low <= high&&k>=1) {
  36. mid = low + F[k - 1] - 1;
  37. if (key < a[mid]) {
  38. high = mid - 1;
  39. k = k - 1;
  40. }
  41. else if (key > a[mid]) {
  42. low = mid + 1;
  43. k = k - 2;
  44. }
  45. else {
  46. if (mid <= high) {
  47. //mid即为查找到的位置
  48. return mid;
  49. }
  50. else {
  51. //扩展的数组,返回n-1
  52. return n - 1;
  53. }
  54. }
  55. }
  56. return -1;
  57. }
  58. int main() {
  59. int A[] = { 1,3,5,7,10,11,15,18,19,22,24,25 };
  60. int res = Fibonacci_Search(A, 12, 1);
  61. cout << res;
  62. return 0;
  63. }

7.1.3 静态树表查找

静态树表将有序表中数据元素按照被查找概论的不同生成一棵二叉树,概率最大的数据放在根的位置或者放在离根较近的位置,同时也使得从二叉树的根结点起,查找左右子树的概率大致相等,使平均查找长度较短。
image.png
image.png