Las respuestas anteriores solo abordan alternativas de árbol y el rojo negro probablemente solo permanezca por razones históricas.
¿Por qué no una tabla hash?
Un tipo solo requiere que el <
operador (comparación) se use como clave en un árbol. Sin embargo, las tablas hash requieren que cada tipo de clave tenga una hash
función definida. Mantener los requisitos de tipo al mínimo es muy importante para la programación genérica, por lo que puede usarlo con una amplia variedad de tipos y algoritmos.
Diseñar una buena tabla hash requiere un conocimiento profundo del contexto en el que se utilizará. ¿Debería usar direccionamiento abierto o encadenamiento vinculado? ¿Qué niveles de carga debe aceptar antes de cambiar el tamaño? ¿Debería usar un hash costoso que evite colisiones, o uno que sea áspero y rápido?
Dado que el STL no puede anticipar cuál es la mejor opción para su aplicación, el valor predeterminado debe ser más flexible. Los árboles "simplemente funcionan" y escalan muy bien.
(C ++ 11 sí agregó tablas hash unordered_map
. Puede ver en la documentación que requiere establecer políticas para configurar muchas de estas opciones).
¿Qué hay de otros árboles?
Los árboles Red Black ofrecen una búsqueda rápida y se equilibran automáticamente, a diferencia de los BST. Otro usuario señaló sus ventajas sobre el árbol AVL de equilibrio automático.
Alexander Stepanov (El creador de STL) dijo que usaría un árbol B * en lugar de un árbol Rojo-Negro si std::map
volviera a escribir , porque es más amigable para las memorias caché modernas.
Uno de los mayores cambios desde entonces ha sido el crecimiento de cachés. Los errores de caché son muy costosos, por lo que la localidad de referencia es mucho más importante ahora. Las estructuras de datos basadas en nodos, que tienen una baja localidad de referencia, tienen mucho menos sentido. Si estuviera diseñando STL hoy, tendría un conjunto diferente de contenedores. Por ejemplo, un árbol B * en memoria es una opción mucho mejor que un árbol rojo-negro para implementar un contenedor asociativo. - Alexander Stepanov
¿Deben los mapas usar siempre árboles?
Otra posible implementación de mapas sería un vector ordenado (clasificación por inserción) y búsqueda binaria. Esto funcionaría bien para contenedores que no se modifican con frecuencia pero se consultan con frecuencia. A menudo hago esto en C como qsort
y estoy bsearch
integrado.
¿Necesito incluso usar el mapa?
Consideraciones de caché significa que rara vez tiene sentido usar std::list
o std::deque
más std:vector
, incluso para aquellas situaciones que nos enseñaron en la escuela (tales como la eliminación de un elemento de la mitad de la lista). Aplicando el mismo razonamiento, usar un bucle for para la búsqueda lineal en una lista es a menudo más eficiente y más limpio que construir un mapa para algunas búsquedas.
Por supuesto, elegir un contenedor legible suele ser más importante que el rendimiento.