Попередні відповіді стосуються лише альтернативних варіантів дерева, а червоний чорний, ймовірно, залишається лише з історичних причин.
Чому б не хеш-таблицю?
Тип вимагає використання лише <
оператора (порівняння) як ключа в дереві. Однак хеш-таблиці вимагають, щоб у кожного типу ключів була hash
визначена функція. Зведення до мінімуму вимог до типу є дуже важливим для загального програмування, тому ви можете використовувати його з найрізноманітнішими типами та алгоритмами.
Розробка хорошої хеш-таблиці вимагає глибокого знання контексту, в якому вона буде використовуватися. Чи слід використовувати відкриту адресацію чи пов'язане ланцюг? Які рівні навантаження слід прийняти перед зміною розміру? Чи слід використовувати дорогий хеш, що дозволяє уникнути зіткнень, або грубу та швидку?
Оскільки STL не може передбачити, який найкращий вибір для вашої програми, за замовчуванням потрібно бути більш гнучким. Дерева «просто працюють» і гарно масштабуються.
(C ++ 11 зробив додавання хеш-таблиць unordered_map
. Ви можете бачити з документації, що вимагає налаштування політики для налаштування багатьох із цих параметрів.)
Що з іншими деревами?
Червоні чорні дерева пропонують швидкий пошук і самоврівноважуються, на відміну від BST. Інший користувач вказав на свої переваги перед самоврівноваженим деревом AVL.
Олександр Степанов (творець STL) сказав, що він буде використовувати B * Дерево замість Червоно-Чорного дерева, якщо він напише std::map
ще раз, оскільки це більш дружнє для сучасних кешів пам'яті.
Однією з найбільших змін відтоді було зростання кеш-пам'яті. Пропуски кешу коштують дуже дорого, тому локальність довіри зараз набагато важливіша. Структури даних на основі вузлів, які мають низьку локальність відліку, мають набагато менший сенс. Якби я сьогодні проектував STL, у мене був би інший набір контейнерів. Наприклад, дерево B * -пам'яті є набагато кращим вибором, ніж червоно-чорне дерево для реалізації асоціативного контейнера. - Олександр Степанов
Чи слід на картах завжди використовувати дерева?
Іншою можливою реалізацією карт буде відсортований вектор (сортування вставки) та двійковий пошук. Це буде добре для контейнерів, які не змінюються часто, але часто запитуються. Я часто роблю це в C як qsort
і bsearch
є вбудованим.
Чи потрібно мені навіть використовувати карту?
Міркування кешу означає , що вона рідко має сенс використовувати std::list
або std::deque
над std:vector
навіть в тих ситуаціях , ми вчили в школі (наприклад, видалення елемента з середини списку). Застосовуючи ті ж міркування, використання циклу для лінійного пошуку списку часто є більш ефективним та чіткішим, ніж створення карти для кількох пошукових запитів.
Звичайно, вибір читабельного контейнера зазвичай важливіший, ніж продуктивність.