ForkJoin全解4:附錄,奇數自加的離散性

/**
 *  求一個hash,然後把hash的結果作爲數組的位置,放入元素,即array[hash]不爲空
 *  現在這個算法是把每次自加後的值作爲數組下標,佔據該下標對應的數組位置,數組被佔
*  據過的位置的值會被置爲1,未被佔據過的位置值爲null。如果在佔據數組中對應位置發現
*  該位置之前被佔據過,這時候就是產生了衝突。如果最後沒有衝突,也沒有不爲null的位置
*  則說明離散性很好
**/
public class HashTest{
    //數組長度必須是2的指數冪
    private final Integer[] array;
    private final int MASK;
    //必須爲奇數,而且任意奇數都可以
    int INCREMENT = 0x0017;
    int s=0;
    /**
     *
     * @param arrayLength,數組長度必須是2的指數冪,比如2,4,8,16
     */
    public HashTest(int arrayLength){
        if(!isPowerOf2(arrayLength)){
            throw new Error("數組長度不是2的指數冪");
        }
        array=new Integer[arrayLength];
        MASK=arrayLength-1;
    }
    private static boolean isPowerOf2(int i){
        if(i<2){
            return false;
        }
        int leadingZeros=Integer.numberOfLeadingZeros(i);
        int shift=30-leadingZeros;
        return i==(2<<shift);
    }
    /**
     *
     * @return 返回偶數位置
     */
    private int hash (){
          return (((s+=INCREMENT)) )&MASK;
    }

    void putElementToHashPosition(){
        for(int i = 0,s=0;i<=MASK;i++){
            int index=hash ();
            Integer a=array[index];
            if(a==null){
                array[index]=1;
            }
            else{
                System.out.println("index="+index+"  i="+i+"  s="+s+"衝突");
            }
        }
        System.out.println("*******************************************");
        for(int i=0;i<array.length;i++){
            if(array[i]==null){
                System.out.println("數組下標i="+i+"     位置元素爲空");
            }
        }
    }
public static void main(String[] args) throws Exception{
    		HashTest hashTest=new HashTest(16);
    	hashTest.putElementToHashPosition();
}
}
輸出結果爲
"*******************************************"

如果把INCREMENT換成偶數,就會出現衝突

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章