Map的python實現


概念

Python中的Dict是一種使用最為普遍的數據結構,特別是數據之間具有關聯關系時。上一博文提到了hash function和hash table的概念,現在來用代碼實現HashTable。
我們通過兩個list來分別存儲key和value,這就要求兩個list的大小一致,在對應的index上分別存儲key和value。實現HashTable最重要的兩個方法是set和get方法,如果通過Class來實現,則需要實現特殊方法__setitem__和__getitem__。這樣就可以通過索引來取值。

構造方法

class HashTable:
    def __init__(self):
        self.size = 11
        self.slots = [None] * self.size
        self.data = [None] * self.size

確定一個HashTable的長度,並且存儲key(slots)和value(data)的list也保持大小一致,且都初始化為None。

hash_function和rehash方法

    def hash_function(self, key, size):
        return key % size

    def rehash(self, old_hash, size):
        return (old_hash + 1) % size

通過hash_function方法確定key在hash table中的索引位置,通過rehash消除collision(不同的key經過hash function計算得到相同的index)。

set方法

    def set(self, key, value):
        hash_value = self.hash_function(key, len(self.slots))
        if self.slots[hash_value] is None:
            self.slots[hash_value] = key
            self.data[hash_value] = value
        else:
            if self.slots[hash_value] == key:
                self.data[hash_value] = value
            else:
                next_slot = self.rehash(hash_value, len(self.slots))
                while self.slots[next_slot] is not None and self.slots[
                    next_slot] != key:
                    next_slot = self.rehash(next_slot, len(self.slots))
                if self.slots[next_slot] is None:
                    self.slots[next_slot] = key
                    self.data[next_slot] = value
                else:
                    self.data[next_slot] = value

set方法的邏輯是:先通過hash function計算key的hash值,然后在保存key的slots(list)中查找對應位置的值是否存在,若不存在,則在該位置保存key,在data(list)中保存key對應的value。
若在slots對應的位置處恰好為key,則update其value。反之,若在slots對應的位置處不為key,則說明發生了collision(數據沖突),那么我們通過rehash方法繼續hash,找到一個空余的位置,將該鍵值對(key和value)放入該位置或僅更新其value。

get方法

    def get(self, key):
        start_slot = self.hash_function(key, len(self.slots))
        position = start_slot
        data = None
        while self.slots[position] is not None:
            if self.slots[position] == key:
                data = self.data[position]
                break
            else:
                position = self.rehash(position, len(self.slots))
                if position == start_slot:
                    break
        return data

get方法較為簡單,也是先獲取hash值,然后查找slots在該hash值處所對應的值是否存在,若存在,則判斷保存的key是否和要查找的key相等,若相等則返回該值,若不相等則說明發生collision,則使用rehash繼續查找。記住,rehash方法必須有一個判斷機制,用以判斷是否遍歷完整個hash table(循環一圈,回到初次hash值)。

__setitem__和__getitem__方法

    def __getitem__(self, key):
        return self.get(key)

    def __setitem__(self, key, value):
        self.put(key, value)

這兩個方法主要是類似Pyhton字典中的set和get語法,如dic[key] = value。

總結:上述實踐僅僅是一個簡單的demo。實際對應hash table的大小,hash function的實現有各個各樣的方法,在這里僅起到一個拋磚引玉的作用。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM