Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.08.15;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.55 MB
Время: 0.034 c
4-1088779601
parovoZZ
2004-07-02 18:46
2004.08.15
WM_PAINT?


1-1091346465
STALKER
2004-08-01 11:47
2004.08.15
Можно ли массив типа Word перевести в массив типа String


3-1090329439
jonik
2004-07-20 17:17
2004.08.15
Lookup поля и SQL сервера


4-1089021102
Storm
2004-07-05 13:51
2004.08.15
завершение процесса


14-1090930907
peypivo
2004-07-27 16:21
2004.08.15
Explorer





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский