查找算法中的散列查找,即利用hash表进行的查找,相对来说能够更快的进行数据的查找,因为它不需要遍历表,而是直接到指定位置进行搜索,平均时间复杂度为O(1),最坏时间复杂度为O(n),查找算法中比较复杂的一个地方就是除数的大小选取。除数的选取采用的是选取离散列表表长最近接的质数或者是所有因子都超过20的合数。本算法采用的是除留余数法,而在冲突处理中采用的是链地址法。具体算法如下:
class element{
int ele;
public element(int num){
this.ele=num;
}
element next=null;
}
public class Hash{
final int len;
element [] array;
public Bicycle(int len){
this.len = calculatePrime(len);
// System.out.println("len is "+this.len);
array = new element[this.len];
for(int i=0;i<array.length;i++){
array[i] = new element(0);
// array[i].ele=0;
}
}
//除留余数法进行定址
/*
* 使用除留余数法的一个经验是,若散列表表长为m,
* 通常p为小于或等于表长(最好接近m)的最小质数或不包含小于20质因子的合数
* tmp即为最终选取的除数p
*/
private int calculatePrime(int len){
ArrayList<Integer> result = new ArrayList<Integer>();
boolean is = true;
int tmp=len;
for(int j=len-5;j<=len;j++){
for(int i=2;i<len/2;i++){
if(j % i==0){
if(isAccepted(j)){
result.add(j);
}
is = false;
break;
}
}
if(is){
result.add(j);
}
is=true;
}
tmp = result.get(0);
for(int i=1;i<result.size();i++){
if(tmp<result.get(i)){
tmp = result.get(i);
}
}
return tmp;
}
private boolean isAccepted(int num){
boolean result = false;
int bound = (int)Math.sqrt(num);
for(int i=2;i<=bound;i++){
if(num % i ==0 && i <20){
break;
}else if(num % i==0 && i>20){
result = true;
}
}
return result;
}
private void hash(int num){
int offset = num % len;
System.out.println("offset is "+offset);
element point = array[offset];
// tmp.ele=num;
while(point.next!=null){
System.out.println("exists!");
point = point.next;
}
point.next = new element(num);
}
public static void main(String [] args){
Hash b = new Hash(100);
int input=0;
while(true){
System.out.println("请输入:");
Scanner sc = new Scanner(System.in);
input = sc.nextInt();
b.hash(input);
for(int i=0;i<b.len;i++){
System.out.print(i+":");
element p = b.array[i];
p = p.next;
while(p!=null){
System.out.print(p.ele+" ");
p =p.next;
}
System.out.println();
}
}
}
}
除数的选择思想就是在表长-5到表长的这5个数中进行选择,首先找到质数,然后将合数进行分解,看是否全部因子都是大于20的,如果符合,则也加入候选动态数组中,然后找出其中最大的作为除数即可。