简体   繁体   English

C ++ STL:二叉搜索树实现?

[英]C++ STL: Binary Search Tree Implementation?

Do you know, please, if C++ STL contains a Binary Search Tree (BST) implementation, or if I should construct my own BST object? 如果C ++ STL包含二进制搜索树(BST)实现,或者我应该构建自己的BST对象,请知道吗?

In case STL conains no implementation of BST, are there any libraries available? 如果STL没有实施BST,是否有可用的库?

My goal is to be able to find the desired record as quickly as possible: I have a list of records (it should not be more few thousands.), and I do a per-frame (its a computer game) search in that list. 我的目标是能够尽快找到所需的记录:我有一个记录列表(它不应该是几千个。),我在该列表中执行每帧(它的计算机游戏)搜索。 I use unsigned int as an identifier of the record of my interest. 我使用unsigned int作为我感兴趣的记录的标识符。 Whatever way is the fastest will work best for me. 无论什么方式,最快的将最适合我。

What you need is a way to look up some data given a key. 您需要的是一种在给定密钥的情况下查找某些数据的方法。 With the key being an unsigned int , this gives you several possibilities. 密钥是unsigned int ,这为您提供了多种可能性。 Of course, you could use a std::map : 当然,你可以使用std::map

typedef std::map<unsigned int, record_t> my_records;

However, there's other possibilities as well. 但是,还有其他可能性。 For example, it's quite likely that a hash map would be even faster than a binary tree. 例如, 哈希映射很可能比二叉树更快 Hash maps are called unordered_map in C++, and are a part of the C++11 standard, likely already supported by your compiler/std lib (check your compiler version and documentation). 散列映射在C ++中称为unordered_map ,并且是C ++ 11标准的一部分,可能已经被编译器/ std lib支持(检查编译器版本和文档)。 They were first available in C++TR1 ( std::tr1::unordered_map ) 它们首先在C ++ TR1中可用( std::tr1::unordered_map

If your keys are rather closely distributed, you might even use a simple array and use the key as an index. 如果您的密钥分布相当紧密,您甚至可以使用简单的数组并使用密钥作为索引。 When it comes to raw speed, nothing would beat indexing into an array. 当涉及到原始速度时,没有什么能够将索引编入数组。 OTOH, if your key distribution is too random, you'd be wasting a lot of space. OTOH,如果你的密钥分配太随意,你就会浪费很多空间。

If you store your records as pointers , moving them around is cheap, and an alternative might be to keep your data sorted by key in a vector: 如果将记录存储为指针 ,那么移动它们很便宜,另一种方法可能是将数据按键在向量中排序:

typedef std::vector< std::pair<unsigned int, record_t*> > my_records;

Due to its better data locality, which presumably plays nice with processor cache, a simple std::vector often performs better than other data structures which theoretically should have an advantage. 由于其更好的数据局部性(可能与处理器缓存相关),简单的std::vector通常比理论上应该具有优势的其他数据结构表现更好。 Its weak spot is inserting into/removing from the middle. 它的弱点是从中间插入/移出。 However, in this case, on a 32bit system, this would require moving entries of 2*32bit POD around, which your implementation will likely perform by calling CPU intrinsics for memory move. 但是,在这种情况下,在32位系统上,这需要移动2 * 32bit POD的条目,您的实现可能会通过调用CPU内在函数来执行内存移动。

std::set and std::map are usually implemented as red-black trees, which are a variant of binary search trees. std::setstd::map通常实现为红黑树,它们是二叉搜索树的变体。 The specifics are implementation dependent tho. 细节是依赖于实现的。

A clean and simple BST implementation in CPP: 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's set class is typically implemented as a BST. STL的集合类通常实现为BST。 It's not guaranteed (the only thing that is is it's signature, template < class Key, class Compare = less<Key>, class Allocator = allocator<Key> > class set; ) but it's a pretty safe bet. 它不是保证(唯一的是它的签名, template < class Key, class Compare = less<Key>, class Allocator = allocator<Key> > class set; )但这是一个非常安全的赌注。

Your post says you want speed (presumably for a tighter game loop). 你的帖子说你想要速度(大概是为了更紧密的游戏循环)。

So why waste time on these slow-as-molasses O(lg n) structures and go for a hash map implementation? 那么为什么要浪费时间在这些缓慢的糖蜜O(lg n)结构上并进行哈希映射实现呢?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM