数据结构-查找-散列表的线性探测已经拉链法的查找

                  哈希表

  先说哈希表散列函数的设计有几种

  1. 直接定址法(一般没啥用,消耗空间太大了)
  2. 除留余数法(一般来说是除以质数,因为质数只有本身和1才可除,这样分布比较均匀,冲突率小)这种方法比较easy也比较常用
  3. 数字分析法(仅仅对那种数据量具有明显区分特征的才管用,并且要先知道有哪些数值,通常情况下数据是随机分布的)
  4. 平方取中法(对关键码平方后取中间几位,因为平方后中间几位比较均匀,不会堆积在一起导致散列后大量冲突,比如123*123=15129,我们可以选51也可以12)
  5. 折叠法(当关键码位数很多的情况下,我们可以用折叠法,)比如把12345678分成123+456+78=xxx然后再对这个数进行散列分析.

  再说下处理冲突的方法

  1. 开放定址法,(用开放定址法得到的散列表叫闭散表)
    1. 线性探测法   这里对关键码去摸后的值冲突的话放到下一个空位置。很简单不多讲。直接将算法
  • 这里我写了4种返回值,对不同情况都有返回。
/*返回正数表示找到的地址
    返回-1表示位找到而且位置全满
    返回-2表示J位置空缺,且已经把查找数插入J位置
    返回-3表示J位置有冲突下,已经探测到后面空缺位置且把j插入
*/
int HashSearch(vector<int>& v,int k)//k是要查找的值,这里假设所有值都是正数,所以初始化的时候V里面全是-1.-1表示空
{
    //获取散列表大小
    int m=v.size();
    //获取散列值 
    int j=H(k);
    //查找一次相同情况下直接返回
    if(v[j]==k)return j;
    //j位置空缺时候,插入,返回-2表示
    else if(v[j]==-1)
    {
         v[j]=k;
         return -2;
    }
    //设置起始位置,加入再次探测到这里还没有表示没有这个数
    int i=(j+1)%m;//这里%m是防止j在散列表的最后导致溢出问题  
    //查找多次
    while(v[i]!=-1&&i!=j)
    {
         if(v[i]==k)return i;
         else i=(i+1)%m;
     }
    if(i==j)
        return -1;//表示没找到
    else
    {
       v[i]=k;
       return -3;//返回-3表示j位置冲突查找不成功后插入
     }
}
                  

  比较常见的处理冲突的方法还有拉链法,为了快捷我们一般用头插法。

  其实就是单链表的查找非常简单

  直接上代码了

 1 //首先解释下这个函数的输入,第一个参数是头结点的链表,第二个参数是m是表长,第三是k表示查找值
 2 Node* Hashsearch(Node* ht[],int m,int k)
 3 {
 4     int j=H(k);//获取散列表 H要自己写
 5     auto p=ht[j];    //这里就像单链表里面的auto p=first一个道理;
 6     while((p!=NULL)&&(p->data!=k))
 7     {
 8         p=p->next;
 9     }
10     if(p->data==k)return p;    //假如找到了就返回这个节点
11     else    //没找到就插入
12     {
13         Node* q=new Node;
14         q->data=k;
15         q->next=p->next;
16         p->next=q;
17
18     }    
19 }

 

转载于:https://www.cnblogs.com/DJC-BLOG/p/9079124.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值