web-dev-qa-db-fra.com

C++ STL: Implémentation de l'arbre de recherche binaire?

Savez-vous s'il vous plaît que/ C++ STL contient un Binary Search Tree (BST) implementation, ou si je dois construire mon propre objet BST?

Si STL ne contient aucune implémentation de BST, y a-t-il des bibliothèques disponibles?

Mon objectif est de pouvoir trouver l'enregistrement souhaité le plus rapidement possible: j'ai une liste d'enregistrements (il ne devrait pas y en avoir plus de quelques milliers) et je fais une image par image rechercher dans cette liste. J'utilise unsigned int comme identifiant de l'enregistrement de mon intérêt. Quel que soit le moyen le plus rapide, cela fonctionnera mieux pour moi.

27
Bunkai.Satori

Ce dont vous avez besoin est un moyen de rechercher des données à partir d’une clé. La clé étant un unsigned int, cela vous donne plusieurs possibilités. Bien sûr, vous pouvez utiliser un std::map

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

Cependant, il y a aussi d'autres possibilités. Par exemple, il est fort probable qu'un une carte de hachage serait encore plus rapide qu'un arbre binaire. Les cartes de hachage sont appelées unordered_map en C++ et font partie du C++ 11 standard, probablement déjà pris en charge par votre compilateur/std lib (vérifiez la version et la documentation du compilateur). Ils étaient d'abord disponibles dans C++ TR1 (std::tr1::unordered_map)

Si vos clés sont assez bien réparties, vous pouvez même utiliser un simple tableau et utiliser la clé comme index. En matière de vitesse brute, rien ne bat l’indexation dans un tableau. OTOH, si votre distribution de clés est trop aléatoire, vous perdriez beaucoup d'espace. 

Si vous enregistrez vos enregistrements sous le nom pointeurs, les déplacer est économique, et vous pouvez également conserver les données triées par clé dans un vecteur: 

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

En raison de sa meilleure localisation des données, qui joue probablement avec Nice avec le cache du processeur, un simple std::vector fonctionne souvent mieux que les autres structures de données qui devraient théoriquement avoir un avantage. Son point faible est l’insertion dans/le retrait du milieu. Toutefois, dans ce cas, sur un système 32 bits, cela nécessiterait le déplacement des entrées de 2 * POD 32 bits, ce que votre implémentation effectuera probablement en appelant des éléments intrinsèques du processeur pour le déplacement de la mémoire. 

33
sbi

std::set et std::map sont généralement implémentés sous la forme d'arbres rouge-noir, qui sont une variante des arbres de recherche binaires. Les spécificités dépendent de la mise en œuvre.

19
ltjax

La classe set de STL est généralement implémentée en tant que BST. Ce n'est pas garanti (la seule chose qui soit, c'est sa signature, template < class Key, class Compare = less<Key>, class Allocator = allocator<Key> > class set;) mais c'est une valeur sûre.

Votre message dit que vous voulez de la vitesse (probablement pour une boucle de jeu plus serrée).

Alors, pourquoi perdre du temps sur ces structures O (lg n) lentes comme de la mélasse et opter pour une implémentation de hash map?

1
corsiKa

Une implémentation BST propre et simple dans CPP:

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;
}
0
amarVashishth