- ベストアンサー
退化木をバランス木にしたい
二分探索木でアドレス帳を作っています。 二分探索木はノードの削除を繰り返すと退化木になってしまいますが、 これを回避するために二分探索木を再構成して、バランス木に近い形にしたいのです。 この二分探索木を再構成するアルゴリズムが全く思いつかず困っています。 詳しい方、ご教授お願い申し上げます。 ちなみに言語はCです。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
ずっと以前に作ったことがあるので、うろ覚えですが・・・。 balance(node) { if (node == NULL) break; nl = count_node(node.left); nr = count_node(node.right); while (abs(nl - nr) > 1) { if (nl > nr+1) { data = get_max_node(node.left); append_node(node.right,data); } else if (nr > nl+1) { data =get_min_node(node.right); append_node(node.left,data); } nl = count_node(node.left); nr = count_node(node.right); } balance(node.left); balance(node.right); } 木のrootに対して、balance(root)を行います。 get_max_node(node)は、node以降の枝から最大のdataを削除し、そのdataを返します。 append_node(node,data)は、node以降の木にdataを追加します。 再帰呼び出しの終了条件がこれで良いかどうか、自信無しです。 文法的にもかなりいいかげんなので、処理の概念の参考程度にして下さい。
その他の回答 (4)
- LCR707
- ベストアンサー率70% (95/135)
#4です。 count_node(node)は、nodeを含み、その枝側のnodeの個数を返します。
お礼
ご回答ありがとうございました。 試してみることにします。 本当にありがとうございました。
- lawson
- ベストアンサー率44% (29/65)
2分木にこだわるなら、バランスを保った 2文探索木でAVL木という概念があります。 ノートを1つ追加した時に、AVL木が崩れた時に。 再構築処理をします。 この 「ノートを1つ追加した時に、AVL木が崩れた時に。 再構築処理をします。 」についてのアルゴリズムを探すとよいと思いますが。かなり複雑な部類にはいるのでそんなに情報もないかも。あったとしても理解できるか・・。 多分木でもよいならNo2さんの回答も参考にして、 B木という方法もあるかも。 あんまりこの手のアルゴリズムをゴリゴリと コードで書くのは、職業PGではあまりしないように 思えます。なにかの研究をするのでなければ、 STL等を学習してデータ処理周りは自分で書かないのが 理想です。 C#や、Javaにおいてもテンプレートのような 型汎用性のあるコードを書けるように進化してきているので、今後はその傾向がますます色濃くなるかも しれないです。
お礼
ご回答頂き、ありがとうございます。
- coredump
- ベストアンサー率46% (12/26)
どもです。 「C―データ構造とプログラム」という本に、 (1) データが昇順で与えられる (2) データの数が予めわかっている を条件に、完全にバランスした2分木を構築する方法が載っています。 なので、そのアプリの起動時等に完全にバランスした2分木にするとかで良いのではないでしょうか。 ちなみにこの本にはB木の構築方法も載っているので、B木にしてしまった方が良いかもしれません。 ではでは。
お礼
ご回答頂き、ありがとうございます。 ご紹介された本を買ってみることにします。
- nofutureforyou
- ベストアンサー率9% (25/277)
データを全部読み出すついでに乱数を付加してそれでソートしてデータを書き戻すというのはどうでしょう?
お礼
ご回答頂き、ありがとうございます。
補足
ご回答ありがとうございます。 count_node関数は何の値を返す関数になるのでしょうか?