C++ STLにBinary Search Tree(BST)実装が含まれている場合、または独自のBSTオブジェクトを構築する必要がある場合、ご存知ですか?
STLがBSTの実装を考慮していない場合、利用可能なライブラリはありますか?
私の目標は、できるだけ早く目的のレコードを見つけることができるようにすることです:私はレコードのリストを持っています(これは数千を超えてはいけません)。コンピューターゲーム)そのリストで検索します。私は、関心のあるレコードの識別子としてunsigned intを使用しています。最速の方法が何であれ、私には最適です。
必要なのは、キーを指定していくつかのデータを検索する方法です。キーがunsigned int
、これはいくつかの可能性を提供します。もちろん、std::map
:
typedef std::map<unsigned int, record_t> my_records;
ただし、他の可能性もあります。たとえば、ハッシュマップは、二分木よりもさらに高速です。ハッシュマップはunordered_map
はC++で、 C++ 11 標準の一部であり、コンパイラ/ std libで既にサポートされている可能性があります(コンパイラのバージョンとドキュメントを確認してください)。これらは、最初に C++ TR1 (std::tr1::unordered_map
)
キーがかなり密に分散している場合は、単純なarrayを使用して、キーをインデックス。生の速度になると、配列へのインデックス付けに勝るものはありません。 OTOH、キーの配布がランダムすぎる場合、多くのスペースを無駄にします。
レコードをpointersとして保存する場合、それらを移動するのは安価であり、代わりにベクトル内のキーでデータを並べ替えます:
typedef std::vector< std::pair<unsigned int, record_t*> > my_records;
データローカリティが優れているため、おそらくプロセッサキャッシュでニースが再生されるため、単純なstd::vector
は、多くの場合、理論的には利点があるはずのその他のデータ構造よりもパフォーマンスがよくなります。その弱点は、中央への挿入/中央からの削除です。ただし、この場合、32ビットシステムでは、これには2 * 32ビットPODのエントリを移動する必要があり、メモリ移動のためにCPU組み込み関数を呼び出すことで実装が実行される可能性があります。
std::set
およびstd::map
は、通常、赤黒木として実装されます。これは、二分探索木の変形です。詳細は実装に依存します。
CPPでのクリーンでシンプルなBST実装:
struct node {
int val;
node* left;
node* right;
};
node* createNewNode(int x)
{
node* nn = new node;
nn->val = x;
nn->left = nullptr;
nn->right = nullptr;
return nn;
}
void bstInsert(node* &root, int x)
{
if(root == nullptr) {
root = createNewNode(x);
return;
}
if(x < root->val)
{
if(root->left == nullptr) {
root->left = createNewNode(x);
return;
} else {
bstInsert(root->left, x);
}
}
if( x > root->val )
{
if(root->right == nullptr) {
root->right = createNewNode(x);
return;
} else {
bstInsert(root->right, x);
}
}
}
int main()
{
node* root = nullptr;
int x;
while(cin >> x) {
bstInsert(root, x);
}
return 0;
}
STLのセットクラスは通常、BSTとして実装されます。保証されていません(唯一のことは、署名、template < class Key, class Compare = less<Key>, class Allocator = allocator<Key> > class set;
)しかし、それはかなり安全な賭けです。
あなたの投稿では、スピードが必要だと言われています(おそらく、より緊密なゲームループのために)。
では、なぜこれらの遅い糖蜜O(lg n)構造に時間を浪費し、ハッシュマップの実装に進むのでしょうか。