Introduction to Algorithms 3rd Ed を読んでいて、いくつかの実用的な状況を実装するのに苦労しています。それは理論ではなく、データ構造自体の内部を実装するのではなく、データ構造を実際のデータの格納に(キーだけでなく)有用なものにする優れたインターフェースを設計する方法です。
具体的には、Cには「プログラマーを信頼する」というタイプの哲学があると言われています。どれだけの信頼があまりにも多くの信頼であるかはわかりません。
例として、多くのデータ構造は、キー、衛星データ、およびds内の他のノードへのポインターを持つ同様のノードを持つリンク構造として実装できます。例:
_typedef struct {
int key;
void *data;
node_t *prev;
node_t *next;
} node_t;
_
実装をどの程度カプセル化する必要がありますか?ほとんどの構造には、(a)データ構造タイプと、(b)データ構造に挿入/削除できるタイプの両方があります。それらは両方とも隠されるべきですか?明らかに、一部の_node_t
_を公開する場合、誰かがkey
と_*data
_ ..のみを変更する意図があります。prev
またはnext
が変更される可能性があります。したがって、データ構造を破壊します。データ構造タイプを公開し、誰かがルートをいじる場合にも、同様のリスクが存在します。
キーはどのように保存/アクセス/比較する必要がありますか?おそらく、キーは衛星データに依存しますが、上記のアプローチをとると、キーをデータ自体から切り離したことになります。ユーザーがデータを更新したがキーを更新し忘れた場合(またはさらに悪いことに、キーを更新したが、DSから削除/再挿入しない場合)はどうなりますか?比較のみを使用するバイナリツリーのようなものの場合、衛星データへのポインタを受け入れるコンパレータを受け入れるようにインターフェイスを設計できますか?これにより構造がより一般化されますが、すべての逆参照は速度に影響を与える必要があります。あるいは(そして、具体的なキーを必要とするハッシュのような構造体に必要になるでしょう)、int toKey(void *data)
functionへのポインターを受け入れることができます。
現実の世界で使用するために優れたソフトウェアをどのように設計すべきかについてはわかりません。
Add()
やRemove()
などのデータ構造を操作するためのメソッドを提供して、コンシューマーがノードに直接触れる必要がないようにします。