std::map, красно-чёрное (не) прошитое дерево?
От: fk0 Россия https://fk0.name
Дата: 11.08.22 08:32
Оценка:
К вопросу о C++, как operator++ работает в std::map? Ведь обход двоичного (красно-черного)
дерева требует стека и рекурсии в общем случае. А если в итераторе только ссылка на один текущий узел,
то поиск следующего по порядку превращается в нетривиальную задачу для "листьев" дерева: нужно подняться
наверх до узла имеющего "правого" наследника и спуститься вниз. Не быстро.

Вот тут какой-то треш с циклами:
https://stackoverflow.com/questions/17150544/what-is-the-definition-of-rb-tree-increment-in-bits-stl-tree-h/17150988#17150988

Для решения подобной проблемы известны прошитые деревья, но почему STL их не использует?
Для различения указателей и прошивки можно использовать раскрашенные указатели, благо у узла выравнивания явно чётное.
Re: std::map, красно-чёрное (не) прошитое дерево?
От: σ  
Дата: 11.08.22 08:48
Оценка:
fk0>Для решения подобной проблемы известны прошитые деревья, но почему STL их не использует?

Потому что и так сойдёт.
Re: std::map, красно-чёрное (не) прошитое дерево?
От: Videoman Россия https://hts.tv/
Дата: 11.08.22 09:03
Оценка:
Здравствуйте, fk0, Вы писали:

fk0>Для решения подобной проблемы известны прошитые деревья, но почему STL их не использует?


Потому-что, как обычно всё в STL, пытаются балансировать по занимаемой памяти и скорости. Если решение общее и не известно как это дерево будут чаще использовать, такой подход кажется оптимальным. Если дерево позиционируется как map — ассоциативный массив, то эти прошития нафиг не уперлись. Если по дерево необходимо очень быстро ходить туда/сюда, то предпочтительней flatmap какой-нибудь.
Re: std::map, красно-чёрное (не) прошитое дерево?
От: kov_serg Россия  
Дата: 11.08.22 09:05
Оценка:
Здравствуйте, fk0, Вы писали:

fk0>К вопросу о C++, как operator++ работает в std::map? Ведь обход двоичного (красно-черного)

fk0>дерева требует стека и рекурсии в общем случае. А если в итераторе только ссылка на один текущий узел,
fk0>то поиск следующего по порядку превращается в нетривиальную задачу для "листьев" дерева: нужно подняться
fk0>наверх до узла имеющего "правого" наследника и спуститься вниз. Не быстро.
Так количество перемещение пропорциональна высоте дерева, а она имеет логарифмическую зависимость.

fk0>Для решения подобной проблемы известны прошитые деревья, но почему STL их не использует?

Потому как был выбран компромисс. Если вы еще два указателя добавите по будет использоваться больше памяти.
Можно было вообще обойтись без указателя на родителя, но итераторы были бы немного другими.
Re[2]: std::map, красно-чёрное (не) прошитое дерево?
От: fk0 Россия https://fk0.name
Дата: 11.08.22 09:50
Оценка:
Здравствуйте, Videoman, Вы писали:

V>Здравствуйте, fk0, Вы писали:


fk0>>Для решения подобной проблемы известны прошитые деревья, но почему STL их не использует?


V>Потому-что, как обычно всё в STL, пытаются балансировать по занимаемой памяти и скорости. Если решение общее и не известно как это дерево будут чаще использовать, такой подход кажется оптимальным. Если дерево позиционируется как map — ассоциативный массив, то эти прошития нафиг не уперлись. Если по дерево необходимо очень быстро ходить туда/сюда, то предпочтительней flatmap какой-нибудь.


Но ведь прошивка практически ничего не стоит. Она не занимает памяти, она ускоряет итератор, она незначительно замедляет (O(1)) прочие операции.
Re[2]: std::map, красно-чёрное (не) прошитое дерево?
От: fk0 Россия https://fk0.name
Дата: 11.08.22 09:54
Оценка:
Здравствуйте, kov_serg, Вы писали:


fk0>>Для решения подобной проблемы известны прошитые деревья, но почему STL их не использует?

_>Потому как был выбран компромисс. Если вы еще два указателя добавите по будет использоваться больше памяти.

Но ведь прошитое дерево не требует дополнительной памяти. Эти два указателя хранятся вместо NULL в листьях
не имеющих дочерних элементов.

_>Можно было вообще обойтись без указателя на родителя, но итераторы были бы немного другими.


Мне кажется, тогда итератор невозможно было бы сделать. Маленький итератор. В условно большом можно
хранить ссылку на дерево и путь в дереве конечно...
Re[3]: std::map, красно-чёрное (не) прошитое дерево?
От: Videoman Россия https://hts.tv/
Дата: 11.08.22 10:34
Оценка:
Здравствуйте, fk0, Вы писали:

fk0> Но ведь прошивка практически ничего не стоит. Она не занимает памяти, она ускоряет итератор, она незначительно замедляет (O(1)) прочие операции.


Значит не всё так просто. Еще один бит признак нужно где-то хранить. Насколько я знаю, некоторые реализации, для хранения признака ч/к узла используют признак четности/не четности адреса. А тут еще один бит нужно где-то хранить. Нужно изучить вопрос. В любом случае, если реализация прошитого дерева действительно не требует затрат по памяти, по скорости и не меняет интерфейс std::map, то можно делать предложения в комитет .
Re[4]: std::map, красно-чёрное (не) прошитое дерево?
От: σ  
Дата: 11.08.22 10:37
Оценка:
V>можно делать предложения в комитет

И... что ты туда напишешь?
Шитое дерево или штопаное, красно-чёрное или серо-зелёное — это чисто деталь реализации.
Отредактировано 11.08.2022 10:39 σ . Предыдущая версия .
Re[5]: std::map, красно-чёрное (не) прошитое дерево?
От: Videoman Россия https://hts.tv/
Дата: 11.08.22 11:06
Оценка:
Здравствуйте, σ, Вы писали:

σ>Шитое дерево или штопаное, красно-чёрное или серо-зелёное — это чисто деталь реализации.


Так вопрос не в этом. Вопрос почему, если якобы одни преимущества и никаких недостатков, почему оно из коробки не такое? Я считаю что нужна дополнительная память. Дерево и так до хрена памяти жрёт, если честно, поэтому я им пользуюсь только в крайних случаях.
Re: std::map, красно-чёрное (не) прошитое дерево?
От: _NN_ www.nemerleweb.com
Дата: 12.08.22 00:15
Оценка:
Здравствуйте, fk0, Вы писали:


fk0>Вот тут какой-то треш с циклами:

fk0>https://stackoverflow.com/questions/17150544/what-is-the-definition-of-rb-tree-increment-in-bits-stl-tree-h/17150988#17150988

fk0>Для решения подобной проблемы известны прошитые деревья, но почему STL их не использует?

fk0>Для различения указателей и прошивки можно использовать раскрашенные указатели, благо у узла выравнивания явно чётное.

Вопрос про реализацию или спецификацию ?
Если реализовать согласно стандарту std::map то выходит красно-чёрное дерево.
Если вам порядок не важен есть std::unordered_map.
Обещают вроде как std::flat_map в C++23.

Стандартная бибилиотека не должна реализовывать все виды деревьев, которые есть.
Для этого есть другие библиотеки.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: std::map, красно-чёрное (не) прошитое дерево?
От: Pzz Россия https://github.com/alexpevzner
Дата: 14.08.22 17:13
Оценка:
Здравствуйте, fk0, Вы писали:


fk0>К вопросу о C++, как operator++ работает в std::map? Ведь обход двоичного (красно-черного)

fk0>дерева требует стека и рекурсии в общем случае. А если в итераторе только ссылка на один текущий узел,
fk0>то поиск следующего по порядку превращается в нетривиальную задачу для "листьев" дерева: нужно подняться
fk0>наверх до узла имеющего "правого" наследника и спуститься вниз. Не быстро.

Да, подняться и опуститься. Overhead точно такой же, как в случае рекурсии, но код на вид более сложный.
Re[3]: std::map, красно-чёрное (не) прошитое дерево?
От: T4r4sB Россия  
Дата: 14.08.22 19:09
Оценка:
Здравствуйте, fk0, Вы писали:

fk0> Но ведь прошитое дерево не требует дополнительной памяти. Эти два указателя хранятся вместо NULL в листьях

fk0>не имеющих дочерних элементов.

Разве в листьях там NULL? А не ссылка на специальный "невалидный" элемент?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.