1 <?xml version="1.0" encoding="UTF-8"?>
3 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
4 * Copyright (C) 2008 - INRIA
5 * Copyright (C) 2012 - 2016 - Scilab Enterprises
6 * Copyright (C) 2018 - 2020 - Samuel GOUGEON
7 * Copyright (C) 2020 - Stanislav KROTER
9 * This file is hereby licensed under the terms of the GNU GPL v2.0,
10 * pursuant to article 5.3.4 of the CeCILL v.2.1.
11 * This file was originally licensed under the terms of the CeCILL v2.1,
12 * and continues to be available under such terms.
13 * For more information, see the COPYING file which you should have received
14 * along with this program.
17 <refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink"
18 xmlns:svg="http://www.w3.org/2000/svg" xmlns:ns5="http://www.w3.org/1999/xhtml"
19 xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook"
20 xmlns:scilab="http://www.scilab.org" xml:id="gsort" xml:lang="ru">
22 <refname>gsort</refname>
23 <refpurpose>сортировка по алгоритму быстрой сортировки</refpurpose>
26 <title>Синтаксис</title>
30 B = gsort(A, method, direction)
31 B = gsort(A, method, directions, rankFuncs)
36 <title>Аргументы</title>
41 Скаляр, вектор, матрица или гиперматрица логических значений, целых,
42 вещественных или комплексных чисел, или текстов. Разрежённые матрицы
43 вещественных чисел, комплексных чисел или логических значений также могут
46 Разрешена перегрузка необрабатываемых типов.
54 Ключевое слово: метод сортировки:
57 <th>'g'</th><td>:</td>
58 <td>Общая сортировка: сортируются все элементы в <literal>A</literal>
59 ( метод по умолчанию).
63 <th>'r'</th><td>:</td>
64 <td>Сортируются строки в каждом столбце в <literal>A</literal>.</td>
67 <th>'c'</th><td>:</td>
68 <td>Сортируются столбцы в каждой строке в <literal>A</literal>.</td>
70 <tr valign="top"><th>'lr'</th><td>:</td>
72 лексикографическая сортировка строк в <literal>A</literal>:
73 Сортируются строки в соответствии со значениями в первом столбце.
74 Если группа сортированных строк имеет то же значение, что и в
75 столбце №1, то группа пересортировывается в соответствии со
76 значениями в столбце №2, и так далее. Не применимо к гиперматрицам.
79 <tr valign="top"><th>'lc'</th><td>:</td>
81 лексикографическая сортировка столбцов в <literal>A</literal>
90 <term>direction</term>
92 направление сортировки:
93 "d": в порядке уменьшения (по умолчанию);
94 "i": в порядке увеличения.
99 <term>directions</term>
101 вектор символов "i" и "d", у которого столько же элементов, сколько
102 элементов имеет <varname>rankFuncs</varname>.
103 <literal>directions(k)</literal> используется для
104 <varname>rankFuncs(k)</varname>.
109 <term>rankFuncs</term>
111 список <literal>list()</literal>, элементы которого имеют следующие типы:
114 идентификатор <literal>fun</literal> функции на языке Scilab,
115 либо встроенной функции.
118 : двоеточие. Ставится для такой <literal>fun</literal>, для которой
119 <literal>fun(A)</literal> возвращает <literal>A</literal>.
122 список <literal>list(fun, param1, param2,..)</literal>, в котором
125 <literal>fun</literal> - это идентификатор функции Scilab или
129 <literal>param1, param2,..</literal> - это параметры.
132 так что будет вызываться <literal>fun(A, param1, param2, ..)</literal>.
136 Функции <literal>fun</literal> должны удовлетворять следующим условиям:
139 должны поддерживаться <literal>R=fun(A)</literal> или
140 <literal>R=fun(A, param1, param2,..)</literal>.
143 <literal>fun</literal> должна работать поэлементно, то есть:
144 <literal>size(R)==size(A)</literal> и <literal>R(k)</literal>
145 по сути равно <literal>A(k)</literal>
148 <literal>R</literal> должен быть простым сортируемым типом:
149 логические значения, целые числа, вещественные значения, текст.
155 Если <literal>A</literal> содержит комплексные числа, то можно
156 определить обычные функции <literal>real, imag, abs, atan</literal>.
157 Тогда <literal>atan(imag(A),real(A))</literal> будет вызываться
158 вместо <literal>atan(A)</literal>.
166 Сортированный массив того же типа, кодирования и размера, что и <literal>A</literal>.
173 Массив десятичных целых чисел размера <literal>size(A)</literal>:
174 исходные индексы элементов <literal>B</literal> в <literal>A</literal>.
175 Если <literal>A</literal> матрица, то в соответствии с выбранным методом
178 <th valign="top">"g"</th><td>:</td>
180 <literal>k</literal> это матрица размером <literal>size(A)</literal>:
181 <literal>k(i)</literal> - это линейный индекс элемента
182 <literal>B(i)</literal> в <literal>A</literal> такой, что <literal>B(:) = A(k)</literal>.
186 <th valign="top">"r"</th><td>:</td>
188 <literal>k</literal> это матрица размером <literal>size(A)</literal>:
189 <literal>k(i,j)</literal> равна <literal>1 ≤ index ≤ size(A,1)</literal>
190 элемента <literal>B(i,j)</literal> в столбце <literal>A(:,j)</literal>.
194 <th valign="top">"c"</th><td>:</td>
196 <literal>k</literal> это матрица размером <literal>size(A)</literal>:
197 <literal>k(i,j)</literal> равна <literal>1 ≤ index ≤ size(A,2)</literal>
198 элемента <literal>B(i,j)</literal> в строке <literal>A(i,:)</literal>.
202 <th valign="top">"lr"</th><td>:</td>
204 <literal>k</literal> - это столбец размером <literal>size(A,1)</literal>
205 такой, что <literal>B = A(k,:)</literal>.
209 <th valign="top">"lc"</th><td>:</td>
211 <literal>k</literal> - это строка размером <literal>size(A,2)</literal>
212 такая, что <literal>B = A(:,k)</literal>.
222 <title>Описание</title>
224 Функция <literal>gsort</literal> выполняет "быструю сортировку" различных типов
225 данных. По умолчанию сортировка выполняется в порядке убывания.
228 Значения <literal>%nan</literal> считаются больше, чем <literal>%inf</literal>.
231 Комплексные числа по умолчанию сортируются только в соответствии с их модулями.
232 Полная сортировка может быть достигнута, используя многоуровневый режим, через
233 аргументы <varname>rankFuncs</varname> и <varname>directions</varname>.
237 <literal>M = gsort(C, "g", ["i" "d"], list(real, imag))</literal><para/>
238 отсортирует массив <literal>C</literal>, сначала в порядке возрастания вещественных
239 частей, и элементов у которых вещественные части равны, а затем в порядке убывания
240 мнимых частей. Многоуровневый режим детально описан в соответствующем подразделе ниже.
243 Тексты сортируются в алфавитном порядке, с учётом регистра.
244 Поддерживаются расширенные UTF-символы.
247 Сортировка массивов логических значений главным образом полезна с помощью методов
248 "r", "c", "lr" или "lc".
252 Какой бы метод ни выбрали, <emphasis role="bold">алгоритм сохраняет относительный порядок элементов с равными значениями</emphasis>.
256 <title>Методы сортировки</title>
258 <emphasis role="bold">B = gsort(A,'g', ..)</emphasis> сортирует все элементы в
259 <varname>A</varname> и сохраняет сортированные элементы в первом столбце сверху
260 вниз, а затем во втором столбце и т.д.
263 <emphasis role="bold">B = gsort(A,'c', ..)</emphasis> сортирует каждую строку в
264 <varname>A</varname>. Каждый сортированный элемент находится в той же строке, что
265 и в <varname>A</varname>, но возможно в другом столбце в соответствии с его
266 рангом сортировки в строке.
269 <emphasis role="bold">B = gsort(A,'r', ..)</emphasis> сортирует каждый столбец в
270 <varname>A</varname>. Каждый сортированный элемент находится в том же столбце,
271 что и в <varname>A</varname>, но возможно в другой строке в соответствии с его
272 рангом сортировки в строке.
275 <emphasis role="bold">B = gsort(A,'lr', ..)</emphasis> сортирует строки в
276 <varname>A</varname> целиком в лексическом порядке. Две строки сравниваются и
277 сортируются следующим образом. Сравниваются элементы их первых столбцов. Если их
278 ранги не равны, то обе строки сортируются соответствующим образом. В противном
279 случае сравниваются элементы их вторых столбцов, и т.д. вплоть до последнего
280 столбца, если это потребуется.
283 <emphasis role="bold">B = gsort(A,'lc', ..)</emphasis> сортируются столбцы в
284 <varname>A</varname> целиком, в лексикографическом порядке (см. выше).
288 <title>Многоуровневая сортировка</title>
290 Как отмечено выше, когда два сравниваемых элемента имеют одинаковые ранги, их
291 исходный относительный порядок в <varname>A</varname> сохраняется в
292 результирующей <varname>B</varname>.
295 Однако, во многих случаях, выходящих за рамки, может быть полезна и затребована
296 многоуровневая сортировка:
297 после выполнения первой сортировки в соответствии с первым критерием и
298 направлением сортировки, можно указать второй критерий и направление сортировки и
299 применить их к одинаковым элементам 1-го ранга, собранным после первой
303 Если после двух первых сортировок некоторые элементы по-прежнему имеют одинаковый
304 ранг, то можно определить и использовать третий уровень сортировки и т.д.
307 <emphasis role="bold">Применимые примеры</emphasis> (смотрите также раздел
311 <emphasis>Сортировка матрицы <literal>C</literal> комплексных чисел,
312 сначала в порядке увеличения модуля, затем в порядке увеличения
315 <literal>gsort(C, "g", ["i" "i"], list(abs, atan))</literal>
319 <emphasis>Сортировка столбцов матрицы <literal>T</literal> текстов,
320 сначала в порядке увеличения длины, затем в обратном алфавитном
323 <literal>gsort(T, "c", ["i" "d"], list(length, :))</literal>
327 <emphasis>Сортировка матрицы <literal>P</literal> полиномов,
328 сначала в порядке увеличения степени, затем в порядке уменьшения значения постоянного коэффициента 0-й степени</emphasis>:
330 function c = get_coef(p, i)
331 // i: степень возвращаемого коэффициента
332 c = matrix(coeff(p(:))(:,i+1), size(p))
335 gsort(P, "c", ["i" "d"], list(degree, list(get_coef,0)))
337 В этом примере функция второго ранжирования позволяет определить степень
338 <literal>i</literal> того коэффициента, который рассматривается в
339 качестве значения вторичной сортировки.
343 <emphasis>Сортировка матрицы <literal>D</literal> десятичных чисел,
344 сначала в порядке возрастания целых частей, затем в порядке уменьшения дробных частей</emphasis>:
346 function r = get_frac(numbers)
347 r = numbers - int(numbers)
350 gsort(D, "g", ["i" "d"], list(int, get_frac))
359 <title>Примеры</title>
361 Сортировка элементов в строках:
364 <programlisting role="example"><![CDATA[
365 m = [ 0. 2. 1. 2. 1. 0.
369 [s, k] = gsort(m, "c")
370 ]]> </programlisting>
372 --> [s, k] = gsort(m, "c")
385 Лексикографическая сортировка строк:
388 <programlisting role="example"><![CDATA[
396 [s, k] = gsort(v,'lr','i'); s, k'
397 ]]> </programlisting>
399 --> [s, k] = gsort(v,'lr','i'); s, k'
413 Лексикографическая сортировка логических столбцов:
416 <programlisting role="example"><![CDATA[
417 m = [ 0 1 0 1 1 1 0 1
419 0 0 1 1 0 0 0 0 ]==1;
421 [s, k] = gsort(m, "lc") // сортировка столбцов в порядке убывания
422 ]]> </programlisting>
430 --> [s, k] = gsort(m, "lc")
437 4. 5. 6. 2. 8. 3. 1. 7.
441 <title>Многоуровневая сортировка</title>
443 <emphasis role="bold">С некоторыми десятичными числами</emphasis>:
444 Сначала сортировка в порядке возрастания целых частей, а затем в порядке убывания
448 <programlisting role="example"><![CDATA[
449 // Функция получения дробных частей
450 function r = get_frac(d)
454 // Несортированные данные
456 2.1 0.1 1.3 1.2 0.1 1.2
457 0.3 1.2 2.3 0.3 1.2 2.1
458 0.1 1.2 1.1 1.2 2.2 1.1
459 2.3 1.3 0.1 2.3 0.1 0.1
460 0.1 2.2 2.1 0.2 1.1 0.3
463 [r, k] = gsort(d, "g", ["i" "d"], list(int, get_frac))
464 ]]> </programlisting>
467 0.3 0.1 0.1 1.2 1.1 2.2
468 0.3 0.1 1.3 1.2 1.1 2.2
469 0.3 0.1 1.3 1.2 2.3 2.1
470 0.2 0.1 1.2 1.2 2.3 2.1
471 0.1 0.1 1.2 1.1 2.3 2.1
474 2. 5. 29. 16. 25. 10.
475 17. 6. 9. 18. 28. 23.
476 30. 14. 11. 22. 4. 1.
477 20. 21. 7. 26. 12. 15.
478 3. 24. 8. 13. 19. 27.
482 <emphasis role="bold">С комплексными числами</emphasis>:
483 Сортировка сначала в порядке увеличения вещественных частей, затем в порядке
484 увеличения мнимых частей.
487 <programlisting role="example"><![CDATA[
488 //c = [-1 1 ; -1 0; 0 2; 0 %nan; 0 -1; 0 %inf ; 0 1; 1 %nan ; 1 1; 1 -1 ; -1 %nan ; 1 -%inf]
489 //c = matrix(squeeze(grand(1,"prm",complex(c(:,1), c(:,2)))), [3,4])
490 s = "complex([0,0,-1,-1;0,-1,1,1;1,1,0,0]," + ..
491 "[%inf,2,%nan,1;-1,0,-1,%nan;1,-%inf,1,%nan])";
493 [r, k] = gsort(c, "g", ["i" "i"], list(real, imag))
494 ]]> </programlisting>
498 0. + Infi 0. + 2.i -1. + Nani -1. + i
499 0. - i -1. + 0.i 1. - i 1. + Nani
500 1. + i 1. - Infi 0. + i 0. + Nani
503 -1. + 0.i 0. - i 0. + Infi 1. - i
504 -1. + i 0. + i 0. + Nani 1. + i
505 -1. + Nani 0. + 2.i 1. - Infi 1. + Nani
514 <emphasis role="bold">С некоторыми текстами:</emphasis>
515 Сортировка строк в столбцах, сначала в порядке увеличения длины, затем в алфавитном
519 <programlisting role="example"><![CDATA[
521 "cc" "ca" "ab" "bbca" "b" "ccbc" "aab" "bca"
522 "ac" "bba" "aba" "bb" "a" "cac" "b" "b"
523 "aaaa" "ac" "b" "bbca" "bb" "bc" "aa" "ca"
524 "c" "ba" "cbb" "a" "aab" "abbb" "ac" "c"
525 "cbb" "b" "cabb" "bccc" "aba" "acb" "acb" "b"
526 "cba" "cc" "a" "abbb" "ab" "cc" "bba" "caaa"
529 [r, k] = gsort(t, "r", ["i" "i"], list(length, :))
530 ]]> </programlisting>
532 --> [r, k] = gsort(t, "r", ["i" "i"], list(length, :))
534 "c" "b" "a" "a" "a" "bc" "b" "b"
535 "ac" "ac" "b" "bb" "b" "cc" "aa" "b"
536 "cc" "ba" "ab" "abbb" "ab" "acb" "ac" "c"
537 "cba" "ca" "aba" "bbca" "bb" "cac" "aab" "ca"
538 "cbb" "cc" "cbb" "bbca" "aab" "abbb" "acb" "bca"
539 "aaaa" "bba" "cabb" "bccc" "aba" "ccbc" "bba" "caaa"
542 4. 5. 6. 4. 2. 3. 2. 2.
543 2. 3. 3. 2. 1. 6. 3. 5.
544 1. 4. 1. 6. 6. 5. 4. 4.
545 6. 1. 2. 1. 3. 2. 1. 3.
546 5. 6. 4. 3. 4. 4. 5. 1.
547 3. 2. 5. 5. 5. 1. 6. 6.
550 <!-- Display up to 6.0.2 (without extra blank lines)
553 !ac ac b bb b cc aa b !
554 !cc ba ab abbb ab acb ac c !
555 !cba ca aba bbca bb cac aab ca !
556 !cbb cc cbb bbca aab abbb acb bca !
557 !aaaa bba cabb bccc aba ccbc bba caaa !
560 <emphasis role="bold">С некоторыми полиномами:</emphasis>
561 Сортировка сначала в порядке уменьшения значений x^0, затем в порядке увеличения
565 <programlisting role="example"><![CDATA[
566 function c = get_coef(p, d)
567 // d : степени возвращаемых коэффициентов
568 c = matrix(coeff(p(:))(:,d+1), size(p))
571 P = ["[-x,1-2*x,2+2*x,1-x,2,-1-x;"
572 "1-x,-1+x,-1,x,1+2*x,2*x;"
573 "-2+x,1,-2,2+x,-x,-1-x]"];
578 [r, k] = gsort(P, "g", ["d" "i"], list(list(get_coef, 0), degree))
579 ]]> </programlisting>
583 -x 1 -2x 2 +2x 1 -x 2 -1 -x
584 1 -x -1 +x -1 x 1 +2x 2x
585 -2 +x 1 -2 2 +x -x -1 -x
587 --> [r, k] = gsort(P, "g", ["d" "i"], list(list(get_coef, 0), degree))
590 2 +2x 1 -x 1 +2x -x -1 +x -2
591 2 +x 1 -2x -x 2x -1 -x -2 +x
594 13. 6. 10. 11. 8. 18.
601 <refsection role="see also">
602 <title>Смотрите также</title>
603 <simplelist type="inline">
605 <link linkend="comparison">сравнение</link>
608 <link linkend="strcmp">strcmp</link>
611 <link linkend="find">find</link>
614 <link linkend="overloading">перегрузка</link>
619 <title>Литература</title>
620 <para>Quick sort algorithm from Bentley & McIlroy's "Engineering a
621 Sort Function". Software---Practice and Experience,
626 <title>История</title>
629 <revnumber>5.4.0</revnumber>
631 Теперь gsort() может быть перегружена для неуправляемых типов.
635 <revnumber>6.1.0</revnumber>
639 Теперь можно сортировать логические значения.
642 Многоуровневая сортировка, добавленная с помощью опции rankFuncs.
648 <revnumber>6.1.1</revnumber>
650 gsort() ранее была ограничена вещественными или комплексными
651 векторами и только методом 'g'. Теперь она полностью способна
652 к работе с разрежёнными векторами и двумерными матрицами логических,
653 вещественных или комплексных чисел, всеми методами 'g, r, c, lr, lc'.
654 Многоуровневая сортировка возможна для всех типов разрежённых входных данных.