Здається, що скрізь, де я дивлюся, структури даних реалізуються за допомогою червоно-чорних дерев ( std::set
у C ++, SortedDictionary
у C # тощо)
Щойно накривши (a, b), червоно-чорні та AVL дерева в моєму класі алгоритмів, ось що у мене вийшло (також розпитуючи професорів, переглядаючи кілька книжок і трохи гуглившись):
- Дерева AVL мають меншу середню глибину, ніж червоно-чорні дерева, і тому пошук значення в дереві AVL стабільно швидший.
- Червоно-чорні дерева вносять менш структурні зміни, щоб збалансувати себе, ніж дерева AVL, що може зробити їх потенційно швидшими для вставлення / видалення. Я кажу, що це може залежати від витрат на структурну зміну дерева, оскільки це буде багато залежати від часу виконання та впровадження (можливо, функціональна мова також буде абсолютно різною, коли дерево непорушне?)
В Інтернеті є багато орієнтирів, які порівнюють AVL та Червоно-чорні дерева, але мене вразило те, що мій професор в основному сказав, що зазвичай ти робиш одну з двох речей:
- Або ви не дуже переймаєтесь ефективністю, і в цьому випадку 10-20% різниці AVL проти червоно-чорних у більшості випадків взагалі не матимуть значення.
- Або ви дійсно дбаєте про продуктивність, і в такому випадку ви б вирвали і AVL, і червоно-чорні дерева, і поїхали з B-деревами, які можна налаштувати, щоб вони працювали набагато краще (або (a, b) -речі, я ' я покладу всіх в один кошик.)
Причиною цього є те, що B-дерево зберігає дані більш компактно в пам'яті (один вузол містить багато значень) буде значно менше пропусків кеша. Ви також можете налаштувати реалізацію на основі випадку використання та зробити порядок B-дерева залежним від розміру кешу CPU тощо.
Проблема полягає в тому, що я не можу знайти майже жодного джерела, яке б аналізувало використання реальних реалізацій дерев пошуку на реальному сучасному обладнанні. Я переглянув багато книг про алгоритми і не знайшов нічого, що б порівнювало різні варіанти дерев разом, крім того, щоб показати, що одна має меншу середню глибину, ніж інша (що насправді не говорить про те, як дерево буде вести себе в реальних програмах.)
Якщо говорити, чи є конкретна причина, чому червоно-чорні дерева використовуються повсюдно, коли, виходячи з сказаного вище, B-дерева повинні перевершувати їх? (як єдиний орієнтир, який я міг знайти, також показано http://lh3lh3.users.sourceforge.net/udb.shtml , але це може бути лише питанням конкретної реалізації). Або причина, чому всі використовують червоно-чорні дерева, тому що їх досить легко здійснити, або, кажучи іншими словами, важко погано реалізувати?
Крім того, як це змінюється, коли людина переходить до сфери функціональних мов? Схоже, що і Clojure, і Scala використовують масиви Hash, відображені на карті , де Clojure використовує коефіцієнт розгалуження 32.