解答・コメントを送る方法
コメントを送るには2つの方法があります。
- 匿名でコメントを書くログインせずにコメントを書くことができます。 名前は「匿名」となります。
- アカウントを作成してコメントを書くアカウントを作成すると、記名での投稿ができます。 また、プロフィールページが作成され、 簡単なプロフィールや 統計情報が表示されるようになります。
投稿ボタンを押す前に以下の文章を確認してください
- 当サイトへの投稿は クリエイティブ・コモンズ・ライセンス BY(表示)および、その解釈に同意するものとみなされます。各ページには下のようにライセンス表示が行われます。
- あなたの投稿したコード・コメント・トピックが再利用・添削されることを望まない場合は、投稿をお控えください。
- 自分が書いていない、ウェブサイトや書籍などからの無断コピーは著作権の侵害です。著作権者の了解を得るか、自分で0から書いてください。
- 著作権の侵害、名誉毀損、など投稿内容に問題がある場合、削除することがあります。
- これらのことにあなたはあらかじめ同意したものとみなされます。
Post comment
Post a comment to the following challenge:
B+木のノード削除
(Nested
Flatten)
As a reply to the following comment: ihag: Rubyで.追加・削除・検索を実装してみ...(#4708) [show]

ihag
#4708()
[
Ruby
]
Rating6/6=1.00
Rubyで.追加・削除・検索を実装してみました. お題にて示されたデータ構造に対し,ランダムに1~81を削除して最後まで削除できることを確認したほか,ランダムに0~10000の要素を追加したデータ構造を用意し,矛盾なく最後まで削除できることを確認しました.
概要
今回,B+Treeのアルゴリズムを実装したクラスBPlusTreeを作成しました. まず,このクラスの簡単な使い方について説明します.
B+Treeオブジェクトの生成
B+Treeオブジェクト生成の例:
内部節(以下Branch)の持てる分岐の数(最大分岐数)と,葉(以下Leaf)の持てる要素の数は,B+Treeの初期化時に任意の数を設定することができます. この時,各Branchの保持する最小の分岐数は,(最大分岐数 / 2) の切り上げの数となります.最小の要素数についても同様です.
最大分岐数と最大要素数を指定する場合の例:
# Branchの最大分岐数5, Leafの最大要素数3 btree = BPlusTree.new({:maxbranch => 5, :maxentry => 3})追加・削除・検索
追加・削除・検索の例:
btree = BPlusTree.new # キーとデータを追加 btree.add(10, "value10") btree.add(11, "value11") btree.add(12, "value12") btree.add(13, "value13") btree.add(14, "value14") # 削除 btree.delete(13) # 検索 (値取得) pp btree.get(10) # => "value10" pp btree.get(13) # => nil (要素が無いので) # 表示 btree.disp # => 以下を表示 # - Branch(root) [(10), 12] # - Leaf [10, 11] # - Leaf [12, 14, 15] btree.disp(true) # => 第一引数により,Leafのデータを表示するか切り替え # - Branch(root) [(10), 12] # - Leaf [10:value10, 11:value11] # - Leaf [12:value12, 14:value14, 15:value15] # フラットな配列に変換 (全件探索による) pp btree.to_a # => [[10, "value10"], [11, "value11"], # [12, "value12"], [14, "value14"], [15, "value15"]dispメソッドによる表示結果では,Branchの一番目のキーを (...) で括っています.これは「(検索アルゴリズムには影響を及ぼさない)一番目のキーである」程度の控えめな気持ちを表しています.要するに,あまり意味はありません.
その他
ppライブラリ用にpretty_printメソッドを再定義していますので,ppでそれなりに見やすい出力を得ることができます.
pp btreeの出力例:
#<BPlusTree:0x402e7a58 @tree= #<BPlusTree::BPlusTree:0x402e79cc @param={:maxbranch=>3, :minentry=>2, :minbranch=>2, :maxentry=>3}, @root= #<B+T::Branch key:[1, 5] branch: [#<B+T::Branch key:[1, 3] branch: [#<B+T::Leaf key:[1, 2] data:["value01", "value02"]>, #<B+T::Leaf key:[3, 4] data:["value03", "value04"]>]>, #<B+T::Branch key:[5, 7] branch: [#<B+T::Leaf key:[5, 6] data:["value05", "value06"]>, #<B+T::Leaf key:[7, 8, 9] data:["value07", "value08", "value09"]>]>]>>>new_from_assocクラスメソッド
配列により組み上げた任意の構造から,BPlusTreeオブジェクトを得るために,new_from_assocクラスメソッドを定義しています.これは,本お題を達成する上で必要だったために実装しました.
最初はB+Treeのアルゴリズムを素直に使ってキー1~81を順番に追加してゆき,お題にて提示された構造を作ろうとしましたが,B+Treeの追加アルゴリズムは「追加時に最大要素数(分岐数)以上になった場合,2分割してそれぞれをB+Treeに加える」というものですので,詰め方を工夫しないと充填率100%とはならず,隙間が空いてしまいます.今回は,配列で構造を作った後にB+Treeオブジェクトを組み上げるメソッドを定義して対応しました.
new_from_assocクラスメソッドの使用例:
assoc = [[:branch, [1, 4], [[:leaf, [1, 2, 3], ["value01", "value02", "value03"]], [:leaf, [4, 5, 6], ["value04", "value05", "value06"]]]]] btree = BPlusTree.new_from_assoc(assoc) btree.disp # => 以下を表示 # - Branch(root) [(1), 4] # - Leaf [1, 2, 3] # - Leaf [4, 5, 6]クラス説明
BPlusTree::BPlusTree
使用者が直接操作するための入り口となるクラスです.add, delete, get, disp, to_aメソッドなどを定義しています.ルートとなるBranchまたはLeafへの参照を保持しています.
また,B+Treeではルートとなるノードについては特別扱いをする必要がありますが,そうした操作も本クラスで実装しています.
BPlusTree::BPlusTree::Node
Leaf, Branchクラスの基底クラスです.共通のメソッドやアクセサメソッドを定義しています.このクラスのインスタンスが作られることはありません.
BPlusTree::BPlusTree::Leaf
Leafのクラスです.add, deleteなど基本的なメソッドを定義しているほか,自身の分割(split)や,兄弟のLeafと要素を配分(balance),兄弟のLeafを自身に併合(integrate)などのメソッドも定義しています.これらのメソッドは,BPlusTree::BranchクラスやBPlusTree::BPlusTreeクラスから呼ばれます.
BPlusTree::BPlusTree::Branch
Branchのクラスです.Leafと同様,Branchの操作に特有なメソッドを定義しています.
BPlusTree
BPlusTree::BPlusTreeクラスのインスタンスを1つだけ保持し,add, delete, get, disp, to_aメソッドを委譲しています.
本来は特に必要ないクラスですが,BPlusTree::BPlusTree.newなどと打つよりBPlusTree.newとできた方が何かと気分がよいために定義してあります.
Rating6/6=1.00-0+
[ reply ]