2012-06-03 :-)
_ [アルゴリズム][ディジタル探索]アルゴリズム辞典 - ディジタル探索 (C実装)
/* ------------------------------------------------------------------------- * アルゴリズム辞典 * 島内剛一 野下浩平 伏見正則 有沢誠 浜田穂積 * * ディジタル探索 pp. 522-523 * ---------------------------------------------------------------------- */ #include <stdio.h> #include <stdlib.h> typedef struct node { char key; struct node* right; struct node* left; } node; static node head = { 0x0, NULL, NULL }; static char mask[9] = { 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; // 探索 node* search ( char key ) { node* np; int idx; idx = 0; np = head.left; // キーの idx 行が 1(0) ならば右(左)へ while( np != NULL && key != np->key ) { np = ( key & mask[ ++idx ] ) ? np->right : np->left; } return np; } // 挿入 void insert( char key ) { node *np, *father = &head; int idx; // ステップ1 キーの探索 idx = 0; np = father->left; while( np != NULL && key != np->key ) { father = np; np = ( key & mask[ ++idx ] ) ? np->right : np->left; } // ステップ2 キー挿入 if( np != NULL ) printf( "%c はすでにある\n", key ); else { // 新しい節を作り np = calloc( 1, sizeof( node )); // キーを置き親とつなぐ np->key = key; np->right = np->left = NULL; if( key & mask[ idx ] ) father->right = np; else father->left = np; } return; } // 削除 void delete ( char key ) { node *np, *father = &head, *x; int idx; // ステップ1 キーの探索 idx = 0; np = head.left; while( np != NULL && key != np->key ) { father = np; np = ( key & mask[ ++idx ] ) ? np->right : np->left; } // ステップ2 キー削除 if( np == NULL ) { printf( "%c はない\n", key ); return; } // np の子孫中の葉を探す x = np; while( x->left != NULL || x->right != NULL ) { father = x; idx++; x = ( x->left == NULL ) ? x->right : x->left; } // 葉のキーを np に置き、葉を切り離す np->key = x->key; if( x->key & mask[ idx ] ) father->right = NULL; else father->left = NULL; return; } int main( int ac, char** av ) { node *np; insert( 'a' ); insert( 'b' ); insert( 'c' ); insert( 'd' ); np = search( 'a' ); if( np != NULL ) printf( "key hit: %c\n", np->key ); np = search( 'a' ); if( np != NULL ) printf( "key hit: %c\n", np->key ); np = search( 'b' ); if( np != NULL ) printf( "key hit: %c\n", np->key ); delete( 'b' ); printf( "delete key: %c\n", 'b' ); np = search( 'a' ); if( np != NULL ) printf( "key hit: %c\n", np->key ); np = search( 'b' ); if( np != NULL ) printf( "key hit: %c\n", np->key ); delete( 'a' ); printf( "delete key: %c\n", 'a' ); np = search( 'a' ); if( np != NULL ) printf( "key hit: %c\n", np->key ); return; }
% ./a.exe key hit: a key hit: a key hit: b delete key: b key hit: a delete key: a
4320027094
_ [アルゴリズム][ディジタル探索]アルゴリズム辞典 - ディジタル探索 (ruby実装)
# アルゴリズム辞典 # 島内剛一 野下浩平 伏見正則 有沢誠 浜田穂積 # # ディジタル探索 pp. 522-523 require 'pp' class Node attr_accessor :key, :left, :right def initialize(key, left, right) @key = key @left = left @right = right end end class DigitalSearch def initialize() @head = Node.new(0, nil, nil) @mask = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80] end # 探索 def search(key) idx = 0 np = @head.left while np != nil && key != np.key # キーの idx 桁が 1(0) ならば右(左)へ idx += 1 np = (key[0] & @mask[idx] != 0) ? np.right : np.left end return np end # 挿入 def insert(key) father = @head idx = 0 # ステップ1 キーの探索 np = father.left while np != nil && key != np.key father = np idx += 1 np = (key[0] & @mask[idx] != 0) ? np.right : np.left end # ステップ2 キー挿入 if np != nil puts "#{key} はすでにある" else # 新しい節を作り np = Node.new(key, nil, nil) # キーを置き親とつなぐ if key[0] & @mask[idx] != 0 father.right = np else father.left = np end end end # 削除 def delete(key) # ステップ1 キーの探索 idx = 0 np = @head.left while np != nil && key != np.key father = np idx += 1 np = (key[0] & @mask[idx] != 0) ? np.right : np.left end # ステップ2 キー削除 if np == nil puts "#{key} はない" return end # np の子孫中の葉を探す x = np while x.left != nil || x.right != nil father = x idx += 1 x = x.left == nil ? x.right : x.left end # 葉のキーを np に置き、葉を切り離す np.key = x.key if x.key[0] & @mask[idx] != 0 father.right = nil else father.left = nil end end end def main() digi = DigitalSearch.new() digi.insert('a') digi.insert('b') digi.insert('c') digi.insert('d') np = digi.search('a') if np != nil puts "key hit: #{np.key}" end np = digi.search('a') if np != nil puts "key hit: #{np.key}" end np = digi.search('b') if np != nil puts "key hit: #{np.key}" end np = digi.search('c') if np != nil puts "key hit: #{np.key}" end np = digi.search('d') if np != nil puts "key hit: #{np.key}" end digi.delete('b') puts "delete key: b" np = digi.search('a') if np != nil puts "key hit: #{np.key}" end np = digi.search('b') if np != nil puts "key hit: #{np.key}" end digi.delete('a'); puts "delete key: a" np = digi.search('a') if np != nil puts "key hit: #{np.key}" end end main()
% ruby digi.rb key hit: a key hit: a key hit: b key hit: c key hit: d delete key: b key hit: a delete key: a
if 0 がなぜ真になるのだ! と 30 分くらい悩んで ruby だということを思い出した。
Ruby では false または nil だけが偽で、それ以外は 0 や空文字列も含め全て真です。
4320027094
[ツッコミを入れる]