Чому в .NET немає класу Tree <T>?


87

Бібліотека базового класу в .NET має кілька чудових структур даних для колекцій (Список, Черга, Стек, Словник), але як не дивно, вона не містить жодних структур даних для бінарних дерев. Це надзвичайно корисна структура для певних алгоритмів, таких як ті, що використовують переваги різних шляхів обходу. Я шукаю правильно написану, безкоштовну реалізацію.

Я просто сліпий, і не знаходячи його ... чи похований він десь у BCL? Якщо ні, може хтось порекомендувати безкоштовну бібліотеку C # /. NET з відкритим кодом для двійкових дерев? Переважно той, який використовує дженерики.

EDIT: Щоб пояснити, що я шукаю. Мене не цікавлять впорядковані збірники словників, які внутрішньо використовують дерево. Мене насправді цікавить бінарне дерево - таке, яке виставляє свою структуру, щоб ви могли робити щось на зразок видобування піддерев або виконувати обхід вузлів після виправлення. В ідеалі такий клас можна було б розширити, щоб забезпечити поведінку спеціалізованих дерев (наприклад, червоний / чорний, AVL, збалансований тощо).


Домовились. У мене іноді виникає потреба знайти (за час O (Log N)) два вузли, які прив'язують значення (коли значення не знайдено в колекції). Наприклад, колекція (дерево) містить 13 та 17 (серед інших), і я шукаю найбільше менше і менше, ніж 16. Дерево могло б це зробити, але Словники, відсортовані списки та хеш-таблиці приймають O (N) .
Les

Відповіді:


31

Ви маєте рацію, у BCL нічого немає. Я підозрюю, що це тому, що вибір, чи використовувати дерево, як правило, є деталлю реалізації, а в іншому випадку є нетрадиційним способом доступу до даних. Тобто, ви не кажете, "елемент двійкового пошуку # 37"; замість цього ви кажете: "Отримати мені елемент №37".

Але ви заглянули в С5 ? Це дуже зручно, і у них є кілька реалізацій дерева ( 1 , 2 , 3 ).


3
C5 підтримує червоно-чорні дерева, а не B-Tree. Це різні відмінності, про які люди повинні знати. B-Tree є найбільш оптимальним для дерева на основі диска або великого дерева пам'яті. Більше вузлів зберігається в одному і тому ж місці, завдяки чому ви отримуєте кращу продуктивність кешу процесора та швидше читаєте запис на диск.
Ентоні Ламберт,

68

Ви можете визначити свій власний:

public class MyTree<K, V> : Dictionary<K, MyTree<K, V>>
{
    public V Value { get; set; }
}

Або без ключа:

public class MyTree<V> : HashSet<MyTree<V>>
{
    public V Value { get; set; }
}

Однак це вимагає від вас знання, скільки деревних рівнів ви будете обробляти під час компіляції, я помиляюся?
Веверке

1
Ні, компілятор C # підтримує цей синтаксис.
Джейсон,

2
Остерігайтеся, щоб елементи не упорядковувались таким чином
Себастьян

@Veverke Можливо, ви думали про шаблони C ++. Загальні засоби .NET - це типи виконання.
Tom Blodget

Мені цікаво. Як ти цим користуєшся? Практично? Будь-який зразок?
Syaiful Nizam Yahya

39

Що б ви хотіли від такої реалізації?

Бінарне дерево? Червоно-чорний? Дерево Radix? B-дерево? R-дерево? R * -дерево?

Дерево є скоріше шаблоном, ніж структурою даних, і вони, як правило, використовуються там, де важлива продуктивність (тому деталі реалізації, ймовірно, також мають значення). Якби BCL містив якийсь клас дерева, то все одно вам доведеться лише прокрутити свій власний


1
Найкраща відповідь на питання "чому".
Joel Coehoorn,

І це лише дерева пошуку. Є також дерева виразів, рішення, ...
Хенк Холтерман,

Дійсно, деталі реалізації мають значення. У моєму випадку я прагну реалізувати деякі алгоритми, які могли б виконувати різні обходи (інфікс, постфікс) на організованому наборі даних як частину серії перетворень. Деревоподібна структура - найелегантніший спосіб вирішення моєї проблеми.
Л.Бушкін, 02

11
У паралельному всесвіті хтось задає питання: "Чому в .Net немає типів списків?", І вони отримують відповідь: "Що ви хочете від такої реалізації? Масив? Зв'язаний список? Черга? A словник? " Я думаю, що це не послідовна відповідь.
rymdsmurf


12

SortedSet<T>реалізовано у вигляді двійкового дерева пошуку ref . SortedDictionary<TKey, TValue>внутрішньо використовує, SortedSet<T>тому це теж є двійковим деревом пошуку ref .


5
На жаль, це просто реалізації впорядкованих карт та списків. І те, і інше не є корисним для повторного використання як двійкового дерева - ці деревоподібні структури є просто деталлю реалізації колекції. Я насправді шукаю клас, який розкриває структуру дерева.
Л.Бушкін 02

9

Ні, Tree<T>у BCL немає жодного " подібного" типу (те, що завжди мене також бентежило), але ось хороша стаття, яка допоможе вам впровадити власну в C #.

Я думаю, ви могли б аргументувати, що структури даних на основі дерев рідше використовуються у тих програмах, для яких зазвичай використовується .NET (бізнес-програми, програми, що переміщують дані тощо). Тим не менше, я погоджуюсь з вами, дивно, що BCL взагалі не має реалізації.



-5

Там в TreeNode ви можете використовувати. Він не є загальним і прихований у віконних формах і використовується з елементом керування деревом, але ви можете використовувати його і в інших місцях.


Так, але він просто має властивість Tag System.Object ype. Немає загального параметра <T>
Генк Холтерман 02

3
Я завжди почуваюся дивно, коли роблю подібні речі. Це менш видно на вашому конкретному прикладі, але якщо люди регулярно переробляють класи з, скажімо, залежностей, це може призвести до важко пояснюваних залежностей і може створити вам проблеми, якщо змінений клас неочікувано зміниться версії залежностей.
Пол Морі, 02

4
Яким би був прибуток від його використання? Вузол дерева зазвичай не має жодної відповідної функціональності. У ньому просто є посилання на дітей та врешті-решт батьків. Немає причин неправильно використовувати клас System.Windows.Forms для нього! Просто напишіть самі - за хвилину чи менше.
user492238
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.