• 散列查找 ← 线性探测法处理冲突


    【算法分析】
    散列查找法主要研究以下两方面的问题:

    (1) 如何构造散列函数?
    实际应用中,有种构造散列函数h()的方法称为除留余数法。因为它计算简单,适用范围非常广,所以成为最常用的构造散列函数的方法。
    除留余数法,即假设散列表的表长为m,选择一个不大于m的数p,用p去除关键字,除后所得余数为散列地址,即
    h(key)=key%p。这个方法的关键是选取适当的p,一般情况下,可以选p为小于表长m的最大质数。例如,表长m=100,可取p=97。
    (2) 如何处理冲突?
    散列法在实际应用中,很难完全避免发生冲突,所以选择一个有效的处理冲突的方法是散列法的另一个关键。本算法采用线性探测法处理冲突,其基本思想是当某一记录的关键字key的初始散列地址d0=h(key)发生冲突时,以d0为基础,采用下文所述线性探测法的数学递推公式计算得到另一个地址d1,如果d1仍然发生冲突,以d1为基础再求下一个地址d2。依次类推,直至dk不发生冲突为止,则dk为该记录在表中的散列地址。通常把寻找“下一个”空位的过程称为探测

    线性探测法计算“下一个”空位的数学递推描述公式为:

    \\ d_0=h(k) \\ d_i=(d_{i-1}+1)\ mod\ m\ (1\leq i\leq m-1)
    其中,h(k)为散列函数,m为散列表表长。

    【算法代码】

    1. #include
    2. using namespace std;
    3. const int m=20; //length of hash table
    4. const int NULLKEY=-12345; //null flag
    5. bool isPrime(int n) {
    6. if(n==1) return false;
    7. for(int i=2; i<=sqrt(n); i++) {
    8. if(n%i==0) return false;
    9. }
    10. return true;
    11. }
    12. int getPrime(int n) { //Get largest prime less than n
    13. for(int i=n-1; i>=2; i--) {
    14. if(isPrime(i)) {
    15. return i;
    16. break;
    17. }
    18. }
    19. }
    20. int H(int key,int p) { //hash function
    21. int ans;
    22. ans=abs(key)%p;
    23. return ans;
    24. }
    25. int hashSearch(vector<int> &a,int key) {
    26. int p=getPrime(m);
    27. int d0=H(key,p);
    28. int di;
    29. if(a[d0]==NULLKEY) return -1;
    30. else if(a[d0]==key) return d0;
    31. else {
    32. for(int i=1; i
    33. di=(d0+i)%m; //Linear detection method
    34. if(a[di]==NULLKEY) return -1;
    35. else if(a[di]==key) return di;
    36. }
    37. return -1;
    38. }
    39. }
    40. int main() {
    41. vector<int> v;
    42. int n; //n
    43. cin>>n;
    44. for(int i=0; i
    45. int x;
    46. cin>>x;
    47. v.push_back(x);
    48. }
    49. int key;
    50. cin>>key;
    51. int t=hashSearch(v,key);
    52. if(t==-1) cout<<"Not found"<
    53. else cout<<"Index is "<
    54. return 0;
    55. }
    56. /*
    57. in:
    58. 16
    59. -7 16 12 68 27 55 -19 20 85 79 10 11 10 -3 -1 7
    60. 12
    61. out:
    62. Index is 2
    63. */



     

  • 相关阅读:
    C++系列-const修饰的常函数
    用亚马逊自养号进行测评的好处
    PMP考试点02
    SQL函数之分割
    ATtiny88初体验(一):点灯
    真相只有一个——谁是凶手
    Spring Boot自定义注解+AOP,使用guava的RateLimiter实现接口的限流
    大模型相关技术了解
    第12章 初识SqlSugarCore之监视Redis性能
    C++模拟实现位图和布隆过滤器
  • 原文地址:https://blog.csdn.net/hnjzsyjyj/article/details/127700847