ホーム » スタッフ » 斉藤徹 » ハッシュ法

2008年11月
« 10月   12月 »
 1
2345678
9101112131415
16171819202122
23242526272829
30  

最近の投稿(電子情報)

アーカイブ

カテゴリー

ハッシュ法

リスト構造から2分木と、高速の検索をする手法として説明したけど、 もっと高速なデータ検索として、ハッシュ法を示す。

メモリ無駄遣い

// 電話番号から名前を調べるために、電話番号自身を保存場所に使えばいい
// しかし、メモリが無駄遣い。
char phone[ 1000000 ][ 10 ] ;
strcpy( 272925 , "斉藤" ) ;

ハッシュ法(衝突無視の場合)

であれば、電話番号の末尾2桁なら、他の人とかぶらないのであれば、 以下の様にすれば、メモリの無駄遣いが防げる。 しかし、末尾2桁が偶然、他の人と同じ場合もありえる。こういう場合をハッシュ衝突と呼ぶ。

#define HASH_SIZE 100
int hash_func( int phone ) {   // ハッシュ関数
return phone % HASH_SIZE ;
}
char phone[ HASH_SIZE ][ 10 ] ;
strcpy( hash_func( 272925 ) , "斉藤" ) ;

クローズドハッシュ法

じゃあハッシュ衝突が発生したら、イス取りゲームの様に、使っていない次のイスに座ればいいじゃん…というのが、クローズドハッシュ法。 授業で説明したときは、うまく配列を定義していなかったので…

struct PhoneName {
int  phone ;       // 電話番号=0 なら「空き」と判定することにする。
char name[ 10 ] ;
} ;
struct PhoneName hash_table[ HASH_SIZE ] ; // hash_table[..].phone = 0 で初期化しておく
void entry( int tel , char name[] ) {
int index = hash_func( tel ) ;
// 空き席を探す                            // 説明の簡略化のため
while( hash_table[ index ].phone != 0 ) {  // 全部の席が埋まっていたときに
index = (index + 1) % HASH_SIZE ;       // 処理を抜ける対策を書かない...
}
// 空いていた席にデータを登録
hash_table[ index ].phone = tel ;
strcpy( hash_table[ index ].name , name ) ;
}
int find( int tel ) {
int index = hash_func( tel ) ;
for( ;; ) { // 説明を簡単にするため、無限ループ対策は書かない。
if ( hash_table[ index ].phone == 0 )
return -1 ;    // 空き席にたどりついた=見つからない。
else if ( hash_table[ index ].phone == tel )
return index ; // 電話番号が一致したので見つかった
else
index = (index + 1) % HASH_SIZE ; // 次の席
}
}