Двоичные деревья поиска
От: Роман Акопов Грузия http://adontz.wordpress.com/
Дата: 25.11.03 16:08
Оценка: 411 (11) +1
Статья:
Двоичные деревья поиска
Автор(ы): Роман Акопов
Дата: 22.05.2004
Статья рассказывает об алгоритмах работы с двоичными деревьями поиска и о красно-черных деревьях (КЧД). Производится сравнение скоростных характеристик различных операций для деревьев и массивов. В прилагаемом С++-коде приводится реализация бинарных деревьев поиска и красно-черных деревьев.


Авторы:
Роман Акопов

Аннотация:
Статья рассказывает об алгоритмах работы с двоичными деревьями поиска и о красно-черных деревьях (КЧД). Производится сравнение скоростных характеристик различных операций для деревьев и массивов.
В прилагаемом С++-коде приводится реализация бинарных деревьев поиска и красно-черных деревьев.
A journey of a thousand miles must begin with a single step © Lau Tsu
Re: Двоичные деревья поиска
От: alexandrov_alex США  
Дата: 26.11.03 07:03
Оценка: +1
Здравствуйте, Роман Акопов, Вы писали:

РА> Статья:

РА>
РА>
РА> Авторы:
РА> Роман Акопов
РА>
РА> Аннотация:
РА> Статья рассказывает об алгоритмах работы с двоичными деревьями поиска и
РА> о красно-черных деревьях (КЧД). Производится сравнение скоростных
РА> характеристик различных операций для деревьев и массивов. В прилагаемом
РА> С++-коде приводится реализация бинарных деревьев поиска и красно-черных
РА> деревьев.

Наверное, я в доску не прав (и статью саму пока не читал), но писать про двоичные деревья в журнале — несколько несерьезно. По двоичным деревьям столько информации на русском — читай не хочу. Если уж рассказывать о красно-черных деревьях, то почему не рассказать и об AVL? Или B-Tree — это самое интересное было бы, они сейчас везде: в СУБД для индексов, в процессорах Intel для страничной адресации памяти, в ядре Windows — вообще для всего.
Еще раз повторю, что саму статью пока не читал, так что готов в любой момент взять свои слова назад (при наличии соответствующих доводов). Ром, я тебя глубоко уважаю — так что не в обиду.

-- Всего хорошего!
-- Alex Alexandrov, e-mail: alex_alexandrov@fromru.com
Posted via RSDN NNTP Server 1.8 beta
It's kind of fun to do the impossible (Walt Disney)
Re[2]: Двоичные деревья поиска
От: adontz Грузия http://adontz.wordpress.com/
Дата: 26.11.03 14:52
Оценка: 16 (2)
Здравствуйте, alexandrov_alex, Вы писали:

_>Наверное, я в доску не прав (и статью саму пока не читал), но писать про двоичные деревья в журнале — несколько несерьезно. По двоичным деревьям столько информации на русском — читай не хочу. Если уж рассказывать о красно-черных деревьях, то почему не рассказать и об AVL? Или B-Tree — это самое интересное было бы, они сейчас везде: в СУБД для индексов, в процессорах Intel для страничной адресации памяти, в ядре Windows — вообще для всего.


Не ты несколько прав. Просто про AVL уже писалив Клиент-Сервере, а до Б-деревьев руки пока не дошли. Всему своё время. Вообще я это задумывал как цикл стаей по относительно сложным структурам данных. Это типа первая. Может продолжу, может нет — это уже как сложится.

_>Еще раз повторю, что саму статью пока не читал, так что готов в любой момент взять свои слова назад (при наличии соответствующих доводов). Ром, я тебя глубоко уважаю — так что не в обиду.


Да не какие обиды. Другое дело, что у нас попросили больше материалов для новичков. Понимаешь на самом деле не правильно писать всё время про никому нафиг не нужные крутые фичи. Это конечно гложит самолюбие автора, но абсолютно бесполезно для 99% читателей. Тебя например сильно волнуют недокументированные счётчики производительности MS SQL Server? Меня например вообще не волнуют, я и документированными то не пользуюсь — нет необходимости. Так что "крутые" статьи конечно тоже нужны, но с другой стороны надо делать материал доступным и начинающим. Если журнал превратится в тусовку для гуру, то хорошо от этого ИМХО никому не будет. В комманде приблизительно такое же мнение. Более того Красно-Чёрные деревье это ещё не простая статья. Стаья на самом деле вышла довольно сложной. Хотелось просто и полно представить метериал. Первое вышло не очень.
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[3]: Двоичные деревья поиска
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 26.11.03 15:12
Оценка:
Здравствуйте, adontz, Вы писали:

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


_>>Наверное, я в доску не прав (и статью саму пока не читал), но писать про двоичные деревья в журнале — несколько несерьезно. По двоичным деревьям столько информации на русском — читай не хочу. Если уж рассказывать о красно-черных деревьях, то почему не рассказать и об AVL? Или B-Tree — это самое интересное было бы, они сейчас везде: в СУБД для индексов, в процессорах Intel для страничной адресации памяти, в ядре Windows — вообще для всего.


Хочу поддержать автора. Знание алгоритмов в том числе и деревянных очень нужная вещь и к сожалению малоиспользующаяся. По Б деревьям в Intel не знаю Хэш таблицы лучше, но Б++ деревья конечно очень эффективны в SortedList и самое главное не дефрагментируют память при неизвестном результирующем размере. А много знаний не бывает. А вот сравнительные характеристики и область применения действительно нужны. Простой пример я применяю простой тип Б деревьев с емкостью страницы 2 в подчиненых группировках для ускорения доступа и экономии памяти т.к. размер подчиненных групировок может быть очень разный и здесь малые Б деревья или красно-черные или AVL очень даже эффективны.
Все зависит от эффективной организации хранения данных.
и солнце б утром не вставало, когда бы не было меня
Re: Двоичные деревья поиска
От: screw_cms Россия ICQ: 168185721
Дата: 27.11.03 11:29
Оценка:
Здравствуйте, Роман Акопов, Вы писали:

А электронная версия статьи (здесь, на сайте) будет ?
When in doubt, use brute force. © Ken Thompson

Re[2]: Двоичные деревья поиска
От: adontz Грузия http://adontz.wordpress.com/
Дата: 27.11.03 12:10
Оценка:
Здравствуйте, screw_cms, Вы писали:

_>А электронная версия статьи (здесь, на сайте) будет ?


Со временем, конечно. Надо пока журнал продать. Кто ж его купит, если статьи из журнала будут на сайте?
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[3]: Двоичные деревья поиска
От: glyph  
Дата: 29.05.04 12:14
Оценка:
Здравствуйте, adontz, Вы писали:
_>>Еще раз повторю, что саму статью пока не читал, так что готов в любой момент взять свои слова назад (при наличии соответствующих доводов). Ром, я тебя глубоко уважаю — так что не в обиду.
A>Да не какие обиды. Другое дело, что у нас попросили больше материалов для новичков. Понимаешь на самом деле не правильно писать всё время про никому нафиг не нужные крутые фичи. Это конечно гложит самолюбие автора, но абсолютно бесполезно для 99% читателей.
Хотел бы предложить в статьях для начитающих так же рассказывать, где это можно применить на практике. Иногда попадаются статьи, интересные как тема для размышлений или начало изучения, но начинающему не всегда сразу ясно, где это можно применить... Чтобы было примерно как в статье про "паттерны проектирования на практике"...
d Apocaliptica-Hyperventilation d
Re: Двоичные деревья поиска
От: Аноним  
Дата: 31.05.04 08:13
Оценка:
Здравствуйте, Роман Акопов, Вы писали:

РА>Статья:



РА>Авторы:

РА> Роман Акопов

РА>Аннотация:

РА>Статья рассказывает об алгоритмах работы с двоичными деревьями поиска и о красно-черных деревьях (КЧД). Производится сравнение скоростных характеристик различных операций для деревьев и массивов.
РА>В прилагаемом С++-коде приводится реализация бинарных деревьев поиска и красно-черных деревьев.

В вашем алгоритме "Удаление вершины из КЧД" есть серьезный недочет. При удалении узла возможна ситуация, когда данные размещенные в узле переходят в другой узел. В результате данные меняют свой адрес в памяти и операция сравнения узлов по их фактическому адресу в памяти становится невозможной. А наличие такой возможности бывает весьма важно для быстрого сравнения узлов. (все статьи о КЧД в сети содержат эту ошибку). Исправьте и будете первым не простым копировальным аппаратом.
Re[2]: Двоичные деревья поиска
От: Аноним  
Дата: 31.05.04 08:56
Оценка:
Здравствуйте, Аноним, Вы писали:

А>В вашем алгоритме "Удаление вершины из КЧД" есть серьезный недочет.


Это не моё алгоритм. Не я его придумал.

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


Для сравнения? Ну я что-нибудь придумаю. Честно говоря первый раз слышу такую просьбу.

А>(все статьи о КЧД в сети содержат эту ошибку).


Я честно говоря видел очень мало статей в которыхъ вообще хоть что-то про удаления вершин сказано

А>Исправьте и будете первым не простым копировальным аппаратом.


Грубовато. Вы же просите всё таки, не так ли?

Роман Акопов
Re[3]: Двоичные деревья поиска
От: Аноним  
Дата: 31.05.04 09:47
Оценка:
Здравствуйте, Аноним, Вы писали:

А>>Исправьте и будете первым не простым копировальным аппаратом.

А>Грубовато. Вы же просите всё таки, не так ли?

Грубые слова беру обратно взад (тем более что и сам не делаю велосипедов), в качестве компенсации могу предложить одну из ссылок

http://algolist.manual.ru/ds/rbtree.php

и код который может пригодиться. Код не элегантен — некогда думать.
Пожалуйста добавьте в статью информацию об адресах узлов. Это действительно важно и полезно (не только мне) для быстрого сравнения узлов (быстрее сравнить адреса, чем сравнивать строки).

free_data — просто функция, которая знает что находится под data и правильно удаляет эту память.


int delete_symbol( struct symbol_table *table, char *id, FREE_NODE_DATA free_data )
{
   int           remove_flag = 1;
   struct node  *x, *y,   *z = lookup( table, id );

   /* delete node z tree */
   if( !z || z == NIL ) return( 0 ); /* Not found */

   if( z->left == NIL || z->right == NIL )
   {
      /* y has a NIL node as a child */
      y = z;
   }
   else
   {
      /* find tree successor with a NIL node as a child */
      y = z->right;
      while( y->left != NIL ) y = y->left;
   }

   /* x is y's only child */
   if( y->left != NIL ) x = y->left;
   else                 x = y->right;

   /* remove y from the parent chain */
   x->parent = y->parent;
   if( y->parent )
   {
      if( y == y->parent->left ) y->parent->left  = x;
      else                       y->parent->right = x;
   }
   else
   {
      table->root = x;
   }
   if( y != z )
   {
      /******************************************************
        Здесь мы делаем перенос данных.
       ******************************************************/
      if( z->id ) free( z->id );
      if( free_data ) free_data( z->data );

      z->id   = y->id;
      z->data = y->data;

      remove_flag = 0;
   }

   if( y->color == BLACK ) delete_fixup( table, x );

   if( remove_flag )
   {
      if( y->id ) free( y->id );
      if( free_data ) free_data( y->data );
      free( y ); 
   }
   else
   {
      /**************************************************
        А здесь делаем подмену узлов.
       **************************************************/
      y->left          = z->left;
      y->left->parent  = y;

      y->right         = z->right;
      y->right->parent = y;

      y->parent = z->parent;
      if( y->parent->left  == z ) y->parent->left  = y;
      if( y->parent->right == z ) y->parent->right = y;

      y->color  = z->color;

      free( z ); 
   }

   return( 1 );

} /* End of delete_symbol() */


Покоцано излишнее цитирование и отформатирован код. С надеждой на понимание — Odi$$ey
Re[2]: Двоичные деревья поиска
От: Аноним  
Дата: 31.05.04 10:55
Оценка:
Здравствуйте, Аноним, Вы писали:

А>В вашем алгоритме "Удаление вершины из КЧД" есть серьезный недочет. При удалении узла возможна ситуация, когда данные размещенные в узле переходят в другой узел. В результате данные меняют свой адрес в памяти и операция сравнения узлов по их фактическому адресу в памяти становится невозможной. А наличие такой возможности бывает весьма важно для быстрого сравнения узлов. (все статьи о КЧД в сети содержат эту ошибку). Исправьте и будете первым не простым копировальным аппаратом.


Итак, немного подумав отвечаю. Речь очевидно идёт об этом куске кода.
  If (nodeParent != node) Then
  Begin
    node.key = nodeParent.key;
    node.color = nodeParent.color;
    { копирование дополнительных данных }
  End

Почему это нельзя заменить на что-то вроде
  If (nodeParent != node) Then
  Begin
    If (node.parent.left == node)
     swap(node.parent.left, nodeParent);
    Else
     swap(node.parent.right, nodeParent);
  End

Первая причина это то, что node.parent может быть NIL, а значит даже если мы и будет копировать указатель, когда node.parent != NIL, это всё равно не защитит нас от смены адреса.
Вторая причина это то, что если мы удалим вершину, а потом добавим, то вновь добавленная вершщина с весьма высокой вероятностью (но не всегда!) моджет обладать тем же адресом, что и только что удалённая. Особенно этим страдают самопальные Heap Managers вроде QuickHeap. Поэтому неправильно сравнивать адреса вершин, они слишком быстро устаревают. Как например устаревают итераторы после добавления в контейнер какого-либо элемента.

Но вы меня натолкнули на некоторую оптимизацию. Как показала практика, хотя случай когда node.parent == NIL и возможен, он достаточно редок и проявляется только когда в дереве малое (порядка 10) количество элементов. поэтому, учитывая что деревья полезны только когда размер данных заметно больше размера ключа, наверное имеет смысл такая оптимизация (я ужt говорю про Си++ код прилагающийся к статье)
При удаление вершины из ДДП эту часть кода (строки 399-400)
lpCTree->key = lpCDelete->key;
lpCTree->data = lpCDelete->data;

заменить на такой код
if (C_Node::IsNull(lpCTree->lpCParent))
{
    lpCTree->key = lpCDelete->key;
    lpCTree->data = lpCDelete->data;
}
else
{
    if (lpCTree->lpCParent->lpCLeft == lpCTree)
    {
        lpCTree->lpCParent->lpCLeft = (C_Node *)&C_Node::nil;
    }
    else
    {
        lpCTree->lpCParent->lpCRight = (C_Node *)&C_Node::nil;
    }
    lpCDelete = lpCTree;    
}

Мои рассуждения и практическая проверка на нескольких сотнях случайных последовательностей показали, что этот код корректен.
Однгако в случае КЧД (строки 679-680) это будет некорректная замена, поскольку ппроцедуре _remove_node_fix (RBTDeleteFixUp) будет передано не совсем то дерево, которое там ожидалось.
Переделывать процедуру RBTDeleteFixUp (довольно сложную) просто так, учитывая что исходный цели (возможность сравнивать вершины по указателям) всё равно в общем случае не добиться, ИМХО не стоит.
Re[3]: Двоичные деревья поиска
От: Аноним  
Дата: 31.05.04 11:15
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Аноним, Вы писали:



А>Переделывать процедуру RBTDeleteFixUp (довольно сложную) просто так, учитывая что исходный цели (возможность сравнивать вершины по указателям) всё равно в общем случае не добиться, ИМХО не стоит.


Согласен, автору этих деревьев надо было подумать об этом сразу, теперь легче все переписать нежели корректно (и на все случаи) исправить существующий код.

Однако, согласны, что людей надо об этом предупреждать?
Re[4]: Двоичные деревья поиска
От: Аноним  
Дата: 31.05.04 12:17
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Согласен, автору этих деревьев надо было подумать об этом сразу, теперь легче все переписать нежели корректно (и на все случаи) исправить существующий код.


Думаю без значительного усложнения код переписать не выйдет. А то выходит все вокруг дураки (вы же не видели желаемой реализации, не так ли), а виноват автор именно этой статьи. Как-то несправедливо

А>Однако, согласны, что людей надо об этом предупреждать?

Предупреждать надо! А о чём? О том что иногда (4-7 раз на 1000 удалений) будет копирование данных? Предупреждаем — будет!
Re: Двоичные деревья поиска
От: Sergeem Израиль  
Дата: 31.05.04 13:51
Оценка:
Здравствуйте, Роман Акопов, Вы писали:

РА>Статья:



РА>Авторы:

РА> Роман Акопов

РА>Аннотация:

РА>Статья рассказывает об алгоритмах работы с двоичными деревьями поиска и о красно-черных деревьях (КЧД). Производится сравнение скоростных характеристик различных операций для деревьев и массивов.
РА>В прилагаемом С++-коде приводится реализация бинарных деревьев поиска и красно-черных деревьев.

а где ссылки на первоисточники?
ведь автор статьи не является автором приведенных алгоритмов и структур данных...
Serge.

Hасколько проще была бы жизнь, если бы она была в исходниках.
Re[2]: Двоичные деревья поиска
От: Аноним  
Дата: 31.05.04 14:13
Оценка:
Здравствуйте, Sergeem, Вы писали:

S>а где ссылки на первоисточники?

Процентов на 80 это http://www.rsdn.ru/res/book/prog/basic_algorithms.xml
Автор(ы): Томас Кормен, Чарльз Лейзерсон, Рональд Ривест
Эта книга — перевод учебника по курсу построения и анализа эффективных алгоритмов, написанного в Массачусетском технологическом институте. В ней разбираются важнейшие классы быстрых алгоритмов и приемы их построения. Изложение подробное и математически строгое. Книгу можно использовать в качестве учебника и справочника; она будет полезна как студентам, так и профессионалам в области информатики и программирования.
Re: Двоичные деревья поиска
От: Wasilij  
Дата: 01.06.04 08:06
Оценка:
Здравствуйте, Роман Акопов, Вы писали:

РА>Статья:



РА>Авторы:

РА> Роман Акопов

РА>Аннотация:

РА>Статья рассказывает об алгоритмах работы с двоичными деревьями поиска и о красно-черных деревьях (КЧД). Производится сравнение скоростных характеристик различных операций для деревьев и массивов.
РА>В прилагаемом С++-коде приводится реализация бинарных деревьев поиска и красно-черных деревьев.

Сводная таблица — это хорошо, но график был бы лучше.

РА> ... Так же надо заметить, что тестирование производилось на объектах относительно малого размера (8 байт), сравнимого с размером указателя (4 байта). Все виды массивов сортированных подразумевают весьма интенсивное копирование элементов, в то время как деревья работают с указателями. При размере элемента, на порядки превышающем размеры указателя, акценты сместятся весьма значительно. ...


Хотелось бы посмотреть на графики, то есть таблицы , 7-12 когда в массиве хранят не сами элементы, а указатели на них.
Re[2]: Двоичные деревья поиска
От: adontz Грузия http://adontz.wordpress.com/
Дата: 01.06.04 11:16
Оценка: 2 (1)
Здравствуйте, Wasilij, Вы писали:

W>Сводная таблица — это хорошо, но график был бы лучше.


Это в редакцию! Считается, что таблицы лучше графиков. Ну да нарисую, не проблема.

W>Хотелось бы посмотреть на графики, то есть таблицы , 7-12 когда в массиве хранят не сами элементы, а указатели на них.


А смысл? Если в качестве данных успользовать указатель на данные, то деревья теряют почти все преимущества перед массивами. Считайте что то что вам надо, это таблицы 1-6 но результаты деревьев ещё хуже.
Если только я правильно понял и вы предлагали вместо такого
class node
 {
  KEY key;
  DATA data;
  node * left;
  node * right;
  node * parent;
 };

предлагаете использовать такое
class node
 {
  KEY key;
  DATA * data;
  node * left;
  node * right;
  node * parent;
 };

Плюс ко всему добавятся тормоза из-за того, что вы будете выделять на каждую вершину по два блока памяти. Для всего кроме данных и для данных. Ну даладно, это уже домыслы

Хотя с другой стороны если у большого количества вершин разные ключи, но одинаковые данные, указанный вами способ хранения может быть весьма удачным. Я бы в таком случае использовал не упросто указатель, а что-то вроде shared_ptr. Ну как бы там ни было вот результаты тестирования, если в качестве данных использовать такой класс.

class autoptr
 {
        private:
            char * ptr;
        public:
            autoptr()
                {
                    ptr = new char[256];
                }
            autoptr(unsigned int)
                {
                    ptr = new char[256];
                }
            autoptr(const autoptr & ap)
                {
                    ptr = new char[256];
                    memmove(ptr, ap.ptr, 256);
                }
            ~autoptr()
                {
                    delete [] ptr;
                }
            autoptr & operator = (const autoptr & ap)
                {
                    delete [] ptr;
                    ptr = new char[256];
                    memmove(ptr, ap.ptr, 256);
                    return *this;
                }
 };

http://www.rsdn.ru/File/2053/RBT-Test-AutoPtr.xls
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[3]: Двоичные деревья поиска
От: Wasilij  
Дата: 01.06.04 12:28
Оценка:
Здравствуйте, adontz, Вы писали:

A>http://www.rsdn.ru/File/2053/RBT-Test-AutoPtr.xls

Прежде всего, спасибо за результаты тестов !

W>>Хотелось бы посмотреть на графики, то есть таблицы , 7-12 когда в массиве хранят не сами элементы, а указатели на них.


A>А смысл? Если в качестве данных успользовать указатель на данные, то деревья теряют почти все преимущества перед массивами. Считайте что то что вам надо, это таблицы 1-6 но результаты деревьев ещё хуже.

A>Если только я правильно понял и вы предлагали вместо такого
A>
A>class node
A> {
A>  KEY key;
A>  DATA data;
A>  node * left;
A>  node * right;
A>  node * parent;
A> };
A>

A>предлагаете использовать такое
A>
A>class node
A> {
A>  KEY key;
A>  DATA * data;
A>  node * left;
A>  node * right;
A>  node * parent;
A> };
A>

A>Плюс ко всему добавятся тормоза из-за того, что вы будете выделять на каждую вершину по два блока памяти. Для всего кроме данных и для данных. Ну даладно, это уже домыслы

Не указатели на данные вместо данных, а указатели на элементы вместо элементов. Мысль была такая: если деревья двигают внутри себя элементы (присваиванием указателя node*), то почему массивы должены копировать эти элементы?
Просто после слов "Хорошо видно, что при увеличенном размере элемента деревья догоняют, а то и значительно обгоняют массивы" совсем за массивы обидно стало .

typedef int KEY;
typedef float DATA;

class node
{
  friend class pnode;
  KEY key;
  DATA data;
  //node * left;
  //node * right;
  //node * parent;
public:
    node( KEY k, DATA d ): key( k ), data( d ) {}
};

class pnode
{
    node * m_pNode;
public:
    pnode( node * pn ): m_pNode( pn ){}
    bool operator < ( const pnode& pn )const
    {
        return m_pNode->key < pn.m_pNode->key;
    }
};

void TestArrayWithPostSort( unsigned int number )
{
  std::vector< pnode > vec;
  vec.reserve( number );
  for( unsigned int index = 0; index < number; index++ )
  {
    vec.push_back( pnode( new node( KEY( index ), DATA( index ) ) ) );
  }
  std::sort( vec.begin(), vec.end() );
    // далее тесты
}


A>Плюс ко всему добавятся тормоза из-за того, что вы будете выделять на каждую вершину по два блока памяти. Для всего кроме данных и для данных.


Согласен, зато нет копирования элементов .
Re[3]: Двоичные деревья поиска
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 01.06.04 12:42
Оценка:
Здравствуйте, adontz, Вы писали:


A>А смысл? Если в качестве данных успользовать указатель на данные, то деревья теряют почти все преимущества перед массивами.

Было бы интересно сравнить с Б+ деревьями.
http://www.rsdn.ru/mag/0603/btree.XML
... << RSDN@Home 1.1.0 stable >>
и солнце б утром не вставало, когда бы не было меня
Re[4]: Двоичные деревья поиска
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 01.06.04 13:03
Оценка:
Здравствуйте, Wasilij, Вы писали:


W>Просто после слов "Хорошо видно, что при увеличенном размере элемента деревья догоняют, а то и значительно обгоняют массивы" совсем за массивы обидно стало .


Тебя и указатели не спасут начиная где то с 20 000 элементов
... << RSDN@Home 1.1.0 stable >>
и солнце б утром не вставало, когда бы не было меня
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.