Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   про метод sort() (https://javascript.ru/forum/dom-window/14102-pro-metod-sort.html)

Иваннн 29.12.2010 17:14

про метод sort()
 
Доброго времени суток! В библии пользователя(Гудман) и подробном руководстве(носорог) по javascript действие метода sort() массива разъясняется так: берется две соседних ячейки и сравниваются. Но в таком масиве [4,5,6,3] каким образом тройка станет вперед, ведь она никак не является соседней для четверки? И еще при использовании аргумента-функции, результатом которой является 1,-1или 0 почему в подробном руководстве говорится, что данная функция запустится всего одлин раз, ведь она должна запускатся при каждом сравнении пар значений?

Kolyaj 29.12.2010 17:27

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

Иваннн 31.12.2010 08:08

А по подробнее про алгоритм?
 
А по подробнее про алгоритм?

Kolyaj 31.12.2010 08:24

http://ru.wikipedia.org/wiki/Quicksort

B@rmaley.e><e 31.12.2010 13:55

Цитата:

Сообщение от Kolyaj
При сортировке используется алгоритм быстрой сортировки

Не везде.
V8: qsort с выбором опоры как среднего из трех и переходом на сортировку вставками для массивов размером меньше 10 (array.js:678).

Spidernonkey: mergesort (jsarray.c:1962).

JavaScriptCore: в коде есть такой комментарий:
Цитата:

// "Min" sort. Not the fastest, but definitely less code than heapsort
// or quicksort, and much less swapping than bubblesort/insertionsort.
(ArrayPrototype.cpp:506)
Как я понял, это сортировка выбором.

Увы, но про Carakan и Charka ничего сказать не могу :-(

JSTalker 06.01.2011 07:29

Цитата:

Сообщение от Kolyaj (Сообщение 85700)
При сортировке используется алгоритм быстрой сортировки, при котором сравниваются не все пары чисел. Callback-функция будет вызвана не один раз.

Т.е. сам sort вызывает эту функцию много (сколько нужно) раз? А программисту достаточно указать один раз sort(foo())?

Вот что сам Флэнэган пишет по этому поводу:

"Для сортировки в какомлибо ином порядке, отличном от алфавитного, можно
передать методу sort() в качестве аргумента функцию сравнения. Эта функция
устанавливает, какой из двух ее аргументов должен присутствовать раньше в от
сортированном списке. Если первый аргумент должен предшествовать второму,
функция сравнения возвращает отрицательное число. Если первый аргумент
в отсортированном массиве должен следовать за вторым, то функция возвращает число, большее нуля. А если два значения эквивалентны (т. е. порядок их рас
положения не важен), функция сравнения возвращает 0."

var a = [33, 4, 1111, 222];
a.sort(); // Алфавитный порядок: 1111, 222, 33, 4
a.sort(function(a,b) { // Числовой порядок: 4, 33, 222, 1111
return a-b; // Возвращает значение < 0, 0, или > 0
}); // в зависимости от порядка сортировки a и b


Откуда тут вообще взялись a и b? Они же нигде явно не определялись.
Понятно, что они как то берутся из массива, но как?

Gvozd 06.01.2011 09:12

Цитата:

Сообщение от JSTalker
Откуда тут вообще взялись a и b? Они же нигде явно не определялись.
Понятно, что они как то берутся из массива, но как?

они передаются функцией sort в callback
то есть когда функция сортировки сранивает два элемента, чтобы определить какой из них должен идти раньше, она вызывает колбек

JSTalker 06.01.2011 23:26

Gvozd,
ух-ты!
Первый раз вижу, чтоб вызывающая функция (sort) передавала (задавала) функции-аргументу (foo()) аргументы...
Алгоритм конечно замысловатый... :blink:

Gvozd 06.01.2011 23:47

JSTalker,
у вас сильные пробелы в базовых знаниях

function func1(funcname, funcparam){
funcname(funcparam);
}
func1(alert,'olo-lo');

Kolyaj 06.01.2011 23:51

JSTalker,
скобочки-то лишние уберите уже наконец.
sort(foo); // а не sort(foo())

JSTalker 07.01.2011 08:01

Цитата:

Сообщение от Gvozd (Сообщение 86550)
JSTalker,
у вас сильные пробелы в базовых знаниях

function func1(funcname, funcparam){
funcname(funcparam);
}
func1(alert,'olo-lo');

вы вообще не о том.
Kolyaj
почему лишние? Это не функциональный литерал (там как бы аргументы подразумеваются).

JSTalker 07.01.2011 08:55

просьба своим языком объяснить этот алгоритм

И как он применяется в JS. А то я что то допереть никак ни могу

JSTalker 07.01.2011 09:24

Цитата:

Быстрая сортировка использует стратегию «разделяй и властвуй». Шаги алгоритма таковы:
1. Выбираем в массиве некоторый элемент, который будем называть опорным элементом. С точки зрения корректности алгоритма выбор опорного элемента безразличен. С точки зрения повышения эффективности алгоритма выбираться должна медиана, но без дополнительных сведений о сортируемых данных её обычно невозможно получить. Известные стратегии: выбирать постоянно один и тот же элемент, например, средний или последний по положению; выбирать элемент со случайно выбранным индексом.
2. Операция разделения массива: реорганизуем массив таким образом, чтобы все элементы, меньшие или равные опорному элементу, оказались слева от него, а все элементы, большие опорного — справа от него. Обычный алгоритм операции:
2.1 Два индекса — l и r, приравниваются к минимальному и максимальному индексу разделяемого массива соответственно.
2.2 Вычисляется индекс опорного элемента m. (??? а п.1 что делал?)
2.3 Индекс l последовательно увеличивается до m до тех пор, пока l-й элемент не превысит опорный.
2.4 Индекс r последовательно уменьшается до m до тех пор, пока r-й элемент не окажется меньше либо равен опорному.
2.5 Если r = l — найдена середина массива — операция разделения закончена, оба индекса указывают на опорный элемент.
2.6 Если l < r — найденную пару элементов нужно обменять местами и продолжить операцию разделения с тех значений l и r, которые были достигнуты. Следует учесть, что если какая-либо граница (l или r) дошла до опорного элемента, то при обмене значение m изменяется на r-й или l-й элемент соответственно.
3. Рекурсивно упорядочиваем подмассивы, лежащие слева и справа от опорного элемента.
4. Базой рекурсии являются наборы, состоящие из одного или двух элементов. Первый возвращается в исходном виде, во втором, при необходимости, сортировка сводится к перестановке двух элементов. Все такие отрезки уже упорядочены в процессе разделения.
вся соль разделения массива заключается в подчеркнутой строчке?

Алгоритм 2.N выполняется только 1 раз для целого массива? Далее он выполняется для левых и правых подмассивов?

Как все это с sort(foo(a,b)) в JS стыкуется?
a,b - это что за элементы относительно вышеописанного?
просто любые 2 элемента, а в функции показано условие?

Kolyaj 07.01.2011 10:15

Цитата:

Сообщение от JSTalker
почему лишние?

Потому что вызываете функцию foo и результат её выполнения передаёте в sort. А нужно передавать в sort саму функцию foo, а не результат её выполнения.

Какая вам разница, как реализована сортировка в JS?

Gvozd 07.01.2011 12:18

Цитата:

Сообщение от JSTalker
a,b - это что за элементы относительно вышеописанного?

это элементы которые сравниваюстя между собой
2.3 и 2.4 содержат операции сравнения элементов(не индексов)

JSTalker 07.01.2011 13:06

Цитата:

Сообщение от Kolyaj (Сообщение 86585)
Потому что вызываете функцию foo и результат её выполнения передаёте в sort. А нужно передавать в sort саму функцию foo, а не результат её выполнения.

Какая вам разница, как реализована сортировка в JS?

Что за вопросы?
Большая.

Иваннн 12.01.2011 10:43

О примере JStalkera
 
Не могу понять логику действий:
-почему у массива нельзя найти медиану(я понимаю середину массива) у любого массива (объект.constructor==Array) есть свойвство length; или обсуждение вышло за рамки метда sort()?
- подчеркнутого пункта - когда проверяется условие I<r (здесь сравнивается значение элемента, а не индексы, иначе нет смысла в слепую менять значения, ориенируясь только на их индексы в массиве.), я думаю проверяется при каждой итерации п.2.3 и п.2.4 (как указал Gvozd).

Раед 24.03.2012 23:43

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

filan 25.03.2012 09:46

Раед,
Если Вы хотите _убрать_ из массива элементы, причем здесь _сортировка_ массива?

Rootpassword 25.03.2012 10:19

Цитата:

Сообщение от Раед
Почитал-почитал, и всё-таки не могу понять этот sort. Например, какую ф-ию передавать ему, если я хочу убрать из массива все элементы со значением undefined.

Ну если вы отсортируете массив, то все такие элементы окажутся в конце. Удалять потом, конечно, будет проще- НО ЗАЧЕМ?

Раед 25.03.2012 11:03

Цитата:

Сообщение от Rootpassword
НО ЗАЧЕМ?

Как зачем? В массиве есть несколько элементов, иногда они из него удаляются, и я хочу, чтобы при удалении все остальные элементы сдвигались. Сделал так:
var arr=[5,8,7,65,64,842,8,42,8,41,6,8,777];
alert(arr.length);
delete arr[4];
delete arr[6];
delete arr[1];
arr = arr.sort(function(a,b){return (b==undefined ? -1 : 0)});
alert(arr.length);
var x = arr.length;
while (arr[--x]==undefined) arr.pop();
alert(arr.length);

Rootpassword 25.03.2012 11:14

Раед, значения undefined в твою функцию сортировки даже не будут переданы, ибо сортируются всегда отдельно.
Во вторых, прямой обход массива -это порядок n. Сравни с сортировкой, которая O(n log n), хотя тут вообще порядок будет n, так как ничего по сути не сортируется + вызовы функции.
Это что? Оптимизация?

Kolyaj 25.03.2012 11:22

Цитата:

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

http://alljs.ru/articles/array/manipulations#splice

antonM 25.03.2012 20:02

Цитата:

Сообщение от Иваннн
почему у массива нельзя найти медиану(я понимаю середину массива) у любого массива (объект.constructor==Array) есть свойвство length

Медиана != Середина массива.
Медиана = середина распределения частот. Лучше всего подходит для характеристики расположения центра распределения для интервальной или относительной шкалы.
Хороший график для понимания:

или


На сколько адекватна будет медиана для такого массива?: [15, "d", 1, "a", 4, "b"]. Кстати стандартный метод, числовую часть сортирует неправильно -> 1,15,4,a,b,d

Раед 25.03.2012 20:40

Цитата:

Сообщение от Rootpassword
прямой обход массива -это порядок n. Сравни с сортировкой, которая O(n log n), хотя тут вообще порядок будет n, так как ничего по сути не сортируется + вызовы функции.

Из этих слов не понял ровным счётом ничего :-?

Раед 25.03.2012 20:42

Цитата:

Сообщение от Rootpassword
ибо сортируются всегда отдельно.

это как, а почему же тогда всё работает?

Rootpassword 25.03.2012 20:57

Цитата:

Сообщение от Раед
это как, а почему же тогда всё работает?

Твоя функция сортировки всегда возвращает 0, т.е. эквивалентность для сортировки, поскольку в function(a,b){return (b==undefined ? -1 : 0)}
undefined сюда не передаются никогда-так уж сортировка устроена в js(да и не только в js, кстати).
Поскольку она утверждает, что все неважно, функция вызывается ровно n-1 раз.

Раед 28.03.2012 12:23

Rootpassword,
Цитата:

Сообщение от Rootpassword
ровно n-1 раз.

Во первых, что такое n
Во вторых, то что undefined в ф-ию не попадают, это я уже понял. Но почему же они оказываются в конце массива?

Rootpassword 28.03.2012 12:49

n, N-всегда количество данных.

Потому что сортируются отдельно, без функции, и записываются в конец. Все !undefined сортируются функцией, и потом все undefined просто добавляются в конец массива.

Раед 31.03.2012 00:58

Цитата:

Сообщение от Rootpassword
потом все undefined просто добавляются в конец массива

То есть можно просто:
arr.sort()

кай 18.11.2012 15:46

Цитата:

Сообщение от JSTalker (Сообщение 86447)
Т.е. сам sort вызывает эту функцию много (сколько нужно) раз? А программисту достаточно указать один раз sort(foo())?

Вот что сам Флэнэган пишет по этому поводу:

"Для сортировки в какомлибо ином порядке, отличном от алфавитного, можно
передать методу sort() в качестве аргумента функцию сравнения. Эта функция
устанавливает, какой из двух ее аргументов должен присутствовать раньше в от
сортированном списке. Если первый аргумент должен предшествовать второму,
функция сравнения возвращает отрицательное число. Если первый аргумент
в отсортированном массиве должен следовать за вторым, то функция возвращает число, большее нуля. А если два значения эквивалентны (т. е. порядок их рас
положения не важен), функция сравнения возвращает 0."

var a = [33, 4, 1111, 222];
a.sort(); // Алфавитный порядок: 1111, 222, 33, 4
a.sort(function(a,b) { // Числовой порядок: 4, 33, 222, 1111
return a-b; // Возвращает значение < 0, 0, или > 0
}); // в зависимости от порядка сортировки a и b


Откуда тут вообще взялись a и b? Они же нигде явно не определялись.
Понятно, что они как то берутся из массива, но как?

вау!


Часовой пояс GMT +3, время: 15:37.