Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.08.15;
Скачать: CL | DM;

Вниз

Добавление элемента в отсортированный массив   Найти похожие ветки 

 
AlexXn   (2004-07-29 12:13) [0]

Как быстро добавить элемент в отсортированный массив(список)


 
Sandman25 ©   (2004-07-29 12:13) [1]

Двоичным поиском


 
Гаврила ©   (2004-07-29 12:14) [2]

пример двоичного поиска - в TStringList, смотри исходник Classes.pas


 
Sandman25 ©   (2004-07-29 12:16) [3]

Кстати, быстро добавить в отсортированный список не получится.


 
AlexXn   (2004-07-29 12:19) [4]

>Sandman25
мне нужно найти именно место куда вставить. Так вот как это сделать быстро
>Гаврила
про двоичный поиск - это я в курсе. Но это найти существующий элемент. А нужно найти место для несуществующего


 
Sandman25 ©   (2004-07-29 12:25) [5]

>А нужно найти место для несуществующего

А это как раз там, где был бы найден элемент, если бы он существовал.
То есть слева элементы меньше него, справа - больше.


 
Poirot ©   (2004-07-29 12:25) [6]

хы))
а если ты добавишь эл-т используя бинарное дерево, то потом при прямом или обратном обходе ты соответственно буишь получать отсортированный массивЖ)
Ну вообщем предлагаю использовать дерево в качестве массива:)))


 
Anatoly Podgoretsky ©   (2004-07-29 12:26) [7]

В массив быстро не получится, а вот в список есть вероятность.


 
Sandman25 ©   (2004-07-29 12:29) [8]

[7] Anatoly Podgoretsky ©   (29.07.04 12:26)

С массивом тоже есть вероятность :)


 
TUser ©   (2004-07-29 12:33) [9]

В список можно добавить быстро, но нельзя быстро найти место, куда вставлять. Ооочень не уверен, но м.б. в случае массива поможет Move. Правильтнее использовать представление этих данных в виде того или иного дерева, например бинарного.
См. Ахо и др., Структуры данных и алгоритмы.


 
Гаврила ©   (2004-07-29 12:37) [10]


> про двоичный поиск - это я в курсе. Но это найти существующий
> элемент. А нужно найти место для несуществующего


Тот алгоритм, который приведен для TStringList, сделает все как надо. Смотри метод Add - он как раз вставляет элемент в нужное место в случае сортированного списка


 
Anatoly Podgoretsky ©   (2004-07-29 12:38) [11]

Sandman25 ©   (29.07.04 12:29) [8]
С массивом нет никакой вероятности, все одназначно.

TUser ©   (29.07.04 12:33) [9]
Это тоже не одназначно, линейный список является массивом. Смотри выше про массивы. Пока не будет уточнения какой список, будет только вероятность.


 
Sandman25 ©   (2004-07-29 12:41) [12]

[11] Anatoly Podgoretsky ©   (29.07.04 12:38)

>В массив быстро не получится, а вот в список есть вероятность.

А если у нас случайно так получилось, что вставляемый элемент должен быть самым последним? Неужели быстро все равно не получится? :)


 
TUser ©   (2004-07-29 12:57) [13]

Anatoly Podgoretsky ©   (29.07.04 12:38) [11]
Я имел в виду связные списки.


 
Anatoly Podgoretsky ©   (2004-07-29 13:28) [14]

Sandman25 ©   (29.07.04 12:41) [12]
Так это и есть вероятность, а вот в свящаный список сама вставка очень быстро, а если список двунапраленый или есть линейный список индексов, то и поиск можно органиховать очень быстро, методом деления по полам. Вставка в связаный список хоть в начало, хоть в середину, хоть в конец занимает одинаковое время.


 
TUser ©   (2004-07-29 13:31) [15]

Что-то я не понял про то, как быстро организовать бинарныйпоискв св.списке, даже если он двунаправленный. Все равно надо перебрать все элементы, пока не найдем нужный. Или не так? Объясните, plz.


 
Romkin ©   (2004-07-29 13:45) [16]

Мудрите вы все. Есть отсортированный массив, надо вставить элемент. Уширяем массив на 1 ячейку, записываем наш элемент последним, и делаем следующее:
сравниваем вставляемый элемент с предыдущим, если он меньше - меняем их местами, снова его на новом месте сравниваем... И так пока предыдущий не окажется меньшим или равным.
А вот вставка с двоичным посиком идет медленнее!


 
Poirot ©   (2004-07-29 13:51) [17]

м.. а ели он самый первый, а массив большой?
Впринципе есть среднее время и вплне возможно они будут сравнимы по порядку..
Тут уже ИМХО опыт поможет!


 
Romkin ©   (2004-07-29 13:57) [18]

В обычный массив вы в любом случае вставите элемент за время О(N). В среднем, при условии равномерно распределенных вставляемых элементов, вы переберете половину массива.
А с двоичным поиском: сначала ищем, куда вставить, это О(log N), а потом-то все равно надо сместить элементы, большие вставляемого на одну позицию, место освободить. Правда, в отличие от моего метода, это можно сделать через move, что эффективнее, чем переставлять по одному, как я предложил.
Но ведь есть же множество типов данных, которые позволяют делать такие операции гораздо быстрее


 
Sandman25 ©   (2004-07-29 14:10) [19]

[11] Anatoly Podgoretsky ©   (29.07.04 12:38)

С массивом нет никакой вероятности, все одназначно.

[14] Anatoly Podgoretsky ©   (29.07.04 13:28)

Так это и есть вероятность

:)


 
Sandman25 ©   (2004-07-29 14:13) [20]

[18] Romkin ©   (29.07.04 13:57)

Не нужно забывать про сравнения.
При двоичном будет log2N сравнений, а при пузырьковом - N/2, что гораздо больше. Причем сравнение может оказаться дорогой операцией.


 
default ©   (2004-07-29 14:16) [21]

поконкретней бы автор обрисовал свою задачу
почему ТАК важна скорость, ...


 
Думкин ©   (2004-07-29 14:20) [22]

> [20] Sandman25 ©   (29.07.04 14:13)

Вот-вот. Сравнение может фактически и съедать все время. И время будет определяться числом сравнений.


 
Palladin ©   (2004-07-29 14:20) [23]


> Romkin ©   (29.07.04 13:57)

Это гораздоэффективней, предложенного "пузырька". И для общих случаев самое оптимальное. Есть поиск более быстрый чем бинарный, интерполяционный. Кнут, однако, всем голова...


> Но ведь есть же множество типов данных,

Да есть, но самое эффективное по скорости доступа к элементам это массив. А обычно именно доступ и важен...


 
Romkin ©   (2004-07-29 14:22) [24]

Уговорили :)))


 
Romkin ©   (2004-07-29 14:25) [25]

Жаль, REPLE нет :(


 
Sandman25 ©   (2004-07-29 14:28) [26]

[23] Palladin ©   (29.07.04 14:20)

Это если первый элемент равен 1, сотый равен 100, а нам нужно найти 58, то мы сразу лезем проверять 58 элемент?


 
Anatoly Podgoretsky ©   (2004-07-29 14:33) [27]

Вопрос про добавление, а не про поиск.
А автор до сих пор молчит, хихикает что ли?


 
Думкин ©   (2004-07-29 14:36) [28]

Обычно быстро надо, если надо много раз вставить. А если так то лучше надописывать, а потом отсортировать и все.


 
Palladin ©   (2004-07-29 14:37) [29]

А это вопрос на какую фразу? :)

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


 
Sandman25 ©   (2004-07-29 14:42) [30]

На Есть поиск более быстрый чем бинарный, интерполяционный :)
Линейная интерполяция


 
Palladin ©   (2004-07-29 14:53) [31]


> [30] Sandman25 ©   (29.07.04 14:42)


Ну почти линейная.

d=trunc((j-i)*(K-K[i])/(K[j]-K[i]))

d расстояние первоначального сравнения. i и j номера соответственно первого и последнего элемента отрезка. Ki и Kj значения элементов в i и j позициях. Если все элементы исходного массива являются(или достаточно близки к ним) членами арифметической прогрессии, то поиск может пройти за одно сравнение. Если не найден нужный ключ с первого раза, то исходный отрезок поиска сужается и делается следующее сравнение с ключом расположенным на новом расстоянии d.

Вот так наглядней
          |(j-i)*(K-K[i])|
   d=trunc|--------------|
          |  K[j] - K[i] |


 
Palladin ©   (2004-07-29 14:55) [32]


> [30] Sandman25 ©   (29.07.04 14:42)


Ну почти линейная.

d=trunc((j-i)*(K-K[i])/(K[j]-K[i]))

d расстояние первоначального сравнения. i и j номера соответственно первого и последнего элемента отрезка. Ki и Kj значения элементов в i и j позициях. Если все элементы исходного массива являются(или достаточно близки к ним) членами арифметической прогрессии, то поиск может пройти за одно сравнение. Если не найден нужный ключ с первого раза, то исходный отрезок поиска сужается и делается следующее сравнение с ключом расположенным на новом расстоянии d.

Вот так наглядней
          |(j-i)*(K-K[i])|
   d=trunc|--------------|
          |  K[j] - K[i] |


 
Palladin ©   (2004-07-29 14:57) [33]

:) Блин... не наглядней...


 
Sandman25 ©   (2004-07-29 14:58) [34]

Спасибо! Понятно.


 
Думкин ©   (2004-07-29 15:04) [35]

>  [32] Palladin ©   (29.07.04 14:55)

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


 
Palladin ©   (2004-07-29 15:07) [36]

Эт точно... Можно даже сказать крайние случаи...


 
default ©   (2004-07-29 15:23) [37]

d=trunc((j-i)*(K-K[i])/(K[j]-K[i]))
лучше так
d=trunc((K-K[i])/((K[j]-K[i])/(j-i)))
так лучше виден смысл этой простенькой формулы с простеньким смыслом)


 
Palladin ©   (2004-07-29 15:32) [38]

Хе :)

Если уж на то пошло, то еще лучше так
Step=(K[j]-K[i])/(j-j);
d=(K-K[i])/Step;


 
Palladin ©   (2004-07-29 15:35) [39]

Что то день сегодня на напряженный для форума...


 
AlexXn   (2004-07-29 15:57) [40]

Спасибо за все ответы всем.
Я вовсе не хихикаю :-)) просто инет у нас "переодический"
если обрисовать картину:
есть список (TList), отсортированный и достаточно большой(около 100К элементов). Необходимо в него добавить элемент. Естественно аккуратно добавить, чтобы не пересортировывать. А добавляется ну скажем не редко :-))) Вот почему важна скорость



Страницы: 1 2 вся ветка

Текущий архив: 2004.08.15;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.025 c
4-1089021258
kvanter
2004-07-05 13:54
2004.08.15
Версионная информация о файле


4-1089095680
bar
2004-07-06 10:34
2004.08.15
Ошибка хука при нажатии WIN+D


1-1091044820
Lego
2004-07-29 00:00
2004.08.15
Как сохранить Canvas, а потом загрузить и продолжить работу ?


14-1091180720
BiN
2004-07-30 13:45
2004.08.15
Всех сисадминов с профессиональным праздником !!!!!


1-1091004689
Shc
2004-07-28 12:51
2004.08.15
Проблемы с MDI формой