1. 程式人生 > >學習筆記:散列

學習筆記:散列

max 去掉 存在 通過 運算 ati ins blog 數值

一、簡述

散列是一種數據訪問技術,所有的數據項均有散列碼與之關聯。

散列碼可在任何時候通過散列函數計算得到,通常為數據索引。

二、散列構造

①直接定址法:取關鍵字本身或其線性函數計算結果作為散列碼。

②數字分析法:取關鍵字中分布較均勻的若幹位作為散列碼。

③折疊法:根據表長取關鍵字拆分為若幹等長部分後疊加求和並去掉進位的結果作為散列碼。(可存在一個不等長部分)

④平方取中法:根據表長取關鍵字平方數值中間的若幹位作為散列碼。

⑤除留余數法:根據表長取關鍵字模運算結果作為散列碼。

三、沖突處理

①開放定址法:沖突發生後從沖突為止進行線性檢索,直到檢索到空的位置插入或搜索項。

②再散列法:沖突發生後使用不同的散列函數生成散列碼,直到沒有沖突為止。

③鏈地址法:每個散列碼對應一個鏈表,直接對相應的鏈表進行查改即可。

④公共溢出區法:將散列表分為基本表和溢出表,將所有發生沖突的數據存入溢出表。

四、實現

①開放定址法

public class HashSet {
    private static final int MAX = 1000;
    private int[] data;

    private int modulo(int val) {
        return val % MAX;
    }

    public HashSet() {
        data = new int[MAX];
        
for (int i = 0; i < MAX; i++) data[i] = Integer.MIN_VALUE; } public boolean add(int val) { int i = modulo(val); while (i < data.length && data[i] != Integer.MIN_VALUE) { if (data[i] == val) return false; else i++; }
if (i < data.length) { data[i] = val; return true; } else return false; } public boolean remove(int val) { int i = modulo(val); while (i < data.length && data[i] != val) i++; if (i < data.length) { data[i] = Integer.MIN_VALUE; return true; } else return false; } public boolean contains(int val) { int i = modulo(val); while (i < data.length && data[i] != val) i++; return i < data.length; } }

②鏈地址法

public class HashSet {
    private class Node {
        int val;
        Node next;

        Node(int x) {
            val = x;
            next = null;
        }
    }

    private static final int MAX = 10000;
    private Node[] heads;

    private int modulo(int val) {
        return val % MAX;
    }

    public HashSet() {
        heads = new Node[MAX];
        for (int i = 0; i < MAX; i++)
            heads[i] = new Node(Integer.MIN_VALUE);
    }

    public boolean add(int val) {
        int i = modulo(val);
        Node x = heads[i];
        while (x.next != null) {
            if (x.next.val == val)
                return false;
            x = x.next;
        }
        x.next = new Node(val);
        return true;
    }

    public boolean contains(int val) {
        int i = modulo(val);
        for (Node x = heads[i]; x.next != null; x = x.next)
            if (x.next.val == val)
                return true;
        return false;
    }

    public boolean remove(int val) {
        int i = modulo(val);
        for (Node x = heads[i]; x.next != null; x = x.next)
            if (x.next.val == val) {
                x.next = x.next.next;
                return true;
            }
        return false;
    }
}

學習筆記:散列