0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

避けて通りたかった Hash chain その(2)

Posted at

こんばんは。
いつも応援有難う御座います。m(_ _)m

前回の続きです。
サラっと書いておいた
dump について補足します。

test.py
    def dump(self):
        # i は table[*] のポインタなので table[i] 
        for i in range(self.capacity):
            # table[i] に格納されている key,value,np を呼び出す 
            p = self.table[i]
            # end=""は、次の print と繋げる記述
            print(i,end="")
            while p is not None:
                #前述 i のすぐ後に以下の記述を表示
                # p.key , p.value を続けて表示
                print(f"=>{p.key}({p.value})",end="")
                # p に np を代入して次の key,value,np に繋げる
                p = p.np
            #改行
            print()

前回書いた数珠つなぎでデータを格納するイメージがあれば
何となくイメージしやすいと思います。

今まで、Hash chain を使って、
データを格納してきました。
格納したのだから、その中からデータを探すアプローチにもチャレンジしましょう。
基本的には既に格納されている Node の中の key に紐づけてデータを探します。

test.py
    def search(self,key):
        # key から table のポインタを割り出します。
        Vhash = key % self.capacity
        p = self.table[Vhash]
        
        while p is not None:
            # 格納された key と入力 key が一致した場合。。
            if p.key == key:
                # データを print で表示
                return print(f"searched value is {p.value}")
            p = p.np
        # while で最後まで該当データを探しても何もない場合、faile
        print("faile to search")

用意した配列に追加して、探したのであれば、
不要項目を削除することも出来ますよね?
チャレンジしてみましょう。
search と同じで、基本的には key で該当 Node を見つけます。
そのあとに、Node から Node の接続点を変えれば削除完了です。
そう、Node 中にある np を編集していきます。

test.py
    def remove(self,key):
        Vhash = key % self.capacity
        p  = self.table[Vhash]
        pp = None # 初期値 None 
        while p is not None:
            if p.key == key
                #最初のデータを削除する場合の記述
                if pp is None:
                    self.table[Vhash] = self.table[Vhash].np
                #最初の項目以外の接続点 np を編集
                else:
                    # pp は後述するがイメージはkey が該当する前の Node
                    # p は key が該当した Node。
                    # pp.np に key が該当した Node の np を代入することで
                    # データの繋ぎから key 該当 Node を削除
                    pp.np = p.np
        # 冒頭の if p.key != key だった場合に pp には p を代入してバッファ
        pp = p            
        # while で先端 Node まで進むために p の値を p.np で更新
        p  = p.np

Hash とは何ぞや?? っという説明をちゃんとしていませんでした。
私の理解では、key を設けることで、該当する配列のポインタを一発で
見つけることができ、そのあとは、線形探索で該当値を探すことができる
面白い探索方法でした。
上記を実現するために勿論、その規則に沿って格納しなければならないです。

今までの記事は与えられた配列を整頓したり、そのままの並びから
探索するアプローチが基本でした。

今回はそうではなく、格納方法そのものを見直して
探索しやすくしている興味深いアルゴリズムでした。( `ー´)ノ

全体像を載せておきます。
最適案があったり、
問題があれば御教示よろしくお願い致しますm(_ _)m。

Chained_hash.py
class Node:
    def __init__(self,key,value,np):
        self.key = key
        self.value = value
        self.np = np

class ChainedHash:
    def __init__(self,capacity):
        self.capacity = capacity
        self.table = [None]*self.capacity
        
    def add(self,key,value):
        
        Vhash = key % self.capacity
        p = self.table[Vhash]
        
        while p is not None:
            if p.key == key:
                return False
            p = p.np
        
        temp = Node(key,value,self.table[Vhash])
        self.table[Vhash] = temp
    
    def dump(self):
        for i in range(self.capacity):
            p = self.table[i]
            print(i,end="")
            while p is not None:
                print(f"=>{p.key}({p.value})",end="")
                p = p.np
            print()
            
    def search(self,key):
        Vhash = key % self.capacity
        p = self.table[Vhash]
        
        while p is not None:
            if p.key == key:
                return print(f"searched value is {p.value}")
            p = p.np
        print("faile to search")
        
    def remove(self,key):
        Vhash = key % self.capacity
        p  = self.table[Vhash]
        pp = None
        while p is not None:
            if p.key == key:
                if pp is None:
                    self.table[Vhash] = self.table[Vhash].np
                else:
                    pp.np = p.np
        pp = p            
        p  = p.np

test = ChainedHash(7)

while True:
    num = int(input("select 1.add, 2.dump, 3.search, 4.remove : "))
    if num == 1:
        key = int(input("key: "))
        val = int(input("val: "))
        test.add(key,val)
    elif num == 2:
        test.dump()
    elif num == 3:
        key = int(input("key: "))
        test.search(key)
    elif num == 4:
        key = int(input("key: "))
        test.remove(key)
    else:
        break  
0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?