(第14讲)哈希表的开放地址法中的二次探测

来源:互联网 发布:js 变量的长度 编辑:程序博客网 时间:2024/05/17 01:47

在线性探测中,已填充单元的长度不断增加,称为首次聚集,这会降低哈希表的性能,二次探测可以消除首次聚集。


Hi=(H(key)+di) MOD m i=1,2,...,k(k<=m-1)其中m为表长,di为增量序列


如果di值可能为1,2的平方,3的平方,...,称二次探测再散列

程序如下:


/**
 * 哈希表的开放地址法中的二次探测
 */
package com.eleven;
public class HashDoubleApp{
    public static void main(String[] args) {
        int size = 10;//哈希表长度
         HashTable2 hashtable = new HashTable2(size);
        /*int num = 8;//哈希表中数据项个数
        int rate = 10;//比率为10,
        
         for(int i =0;i<num;i++){
             int value =(int)( Math.random()*rate*size);//表示关键字范围是120
             //根据关键字创建数据项对象
             Data2 data = new Data2(value);
             //再根据数据项对象,新增哈希表
             hashtable.insert(data);
         }*/
         int arr[] ={79,38,49,18,29};
         for(int i =0;i<arr.length;i++){
             Data2 data = new Data2(arr[i]);
             hashtable.insert(data);
         }
         hashtable.display();
         int findkey = 28;//设置要查找的关键值
         Data2 finddata = hashtable.find(findkey);
         if(finddata!=null)
             System.out.println("找到"+findkey);
         else
             System.out.println("没找到"+findkey);
        
         //删除操作
         int deletekey = 18;
         Data2 deletedata = hashtable.delete(deletekey);
         if(deletedata!=null)
             System.out.println("已经删除"+deletekey);
         else
             System.out.println("该哈希表中不含"+deletekey);
         hashtable.display();
    }

}
//数据类
class Data2{
    private int data;
    public Data2(int data){
        this.data = data;
    }
    public int getData(){
        return data;
    }
}
//哈希表:增,删, 查,遍历
class HashTable2{
    //定义一个数组,存放带关键值的数据项;定义数组的长度;定义被删除的数据项
    private Data2 hashArr[] ;
    private int arrlength;
    private Data2 deleteData;
    //构造函数,初始化三个变量
    public HashTable2(int size){
        arrlength = size;
        hashArr  = new Data2[arrlength];
        deleteData = new Data2(-1);
    }
    //哈希函数:将要输入的关键字或者数据项转换成数组下标
    public int HashFunc(int key){
        return key % arrlength;
    }
    //判断哈希表是否满
    public boolean isFull(){
        int num =0;
        while(hashArr[num]!=null&&num<arrlength){//直到hashArr为空
            num = num+1;
        }
        if(num==arrlength)
            return true;
        else
            return false;
    }
    //增:假设哈希表未满,通过要输入的数据项得到关键值,再将其哈希化,
    //迭代查找哈希表中此下标为空或者此处是被删除项,如果此处不为空,则递增下标继续查找
    //知道找到空的或者被删除的,新增
    public void insert(Data2 value){
        if(!isFull()){
            int key = value.getData();
            int arrIndex = HashFunc(key);//得到哈希化的数组下标
            //寻找哈希表中空的或者被删除的项
            int i = 1;
            while(hashArr[arrIndex]!=null && hashArr[arrIndex].getData()!=-1){
                int step = i*i;
                int index = arrIndex;
                arrIndex += step;
                arrIndex %= arrlength;
                ++i;
                if(hashArr[arrIndex]!=null && hashArr[arrIndex].getData()!=-1){
                    arrIndex = index;
                    }
            }
            hashArr[arrIndex] = value;
        }
    }
    //删:根据关键值删除对应的数据项
    //先转化为数组下标,再得到数组此位置对应的数据项,然后查找,删除并返回
    public Data2 delete(int key){
        int arrIndex = HashFunc(key);
        int temp = arrIndex;
        int i =1;
        while(hashArr[arrIndex]!= null){
            if(hashArr[arrIndex].getData()== key){
                Data2 data = hashArr[arrIndex];
                hashArr[arrIndex] = null;
                return data;
            }
            //如果当前为止没找到,继续找下一个
            arrIndex +=(i*i);
            ++i;
            arrIndex %= arrlength;
            if(hashArr[arrIndex]!= null && hashArr[arrIndex].getData()!=-1 && hashArr[arrIndex].getData()!= key){
                arrIndex = temp;
            }
        }
        return null;//没有找到,
    }
    //查找
    public Data2 find(int key){
        int arrIndex = HashFunc(key);
        int temp = arrIndex;
        int i=1;
        while(hashArr[arrIndex]!=null){
            if(hashArr[arrIndex].getData()==key)
                return hashArr[arrIndex];
            //当前位置没有找到,继续往下一个位置找
            arrIndex +=(i*i);
            ++i;
            arrIndex %= arrlength;
            if(hashArr[arrIndex]!=null && hashArr[arrIndex].getData()!=-1 && hashArr[arrIndex].getData()!= key){
                arrIndex = temp;
                continue;
            }
        }
        return null;//没找到
    }
    //遍历
    public void display(){
        for(int i=0;i<arrlength;i++){
            if(hashArr[i]!=null)
                System.out.print(hashArr[i].getData()+" ");
            else
                System.out.print("** ");
        }
        System.out.println();
        
    }
}

结果是:

49 ** 18 29 ** ** ** ** 38 79
没找到28
已经删除18
49 ** ** 29 ** ** ** ** 38 79



0 0
原创粉丝点击