Методы сортировки одномерных массивов.ppt
- Количество слайдов: 20
Распространенные методы сортировки одномерных массивов
Основные методы сортировки • • Метод «пузырька» Сортировка выбором Сортировка вставками Быстрая сортировка
Метод «пузырька» Идея метода состоит в последовательном перемещении путем попарных перестановок наибольшего значения сначала на место N-го элемента, затем N-1 -го и т. д.
Почему такое название – метод «пузырька» Если в воде находиться пузырёк с воздухом, то он постепенно поднимается наверх. Связано это явление с силой Архимеда: плотность воздуха меньше плотности воды. Сортировка "пузырьком" немного напоминает описанный процесс.
1 вариант метода «пузырька» Program PR 1; Var N, i, j : integer; P: real; A: array [1. . 100] of real; Begin Write(‘введите N’); Readln (N); For i: =1 to N do Begin Write(‘Введите A[‘, i, ’]=’); Readln(A[i]) end; For i: =1 to N – 1 do For j: =1 to N-i do if A[j]<= A[j+1] then begin P: = A[j]; A[j]: =A[j+1]; A[j+1]: =P end; For i: =1 to N do write(A[i]: 7: 3); end. {сортировка по убыванию}
2 вариант метода пузырька Сколько раз просматривается массив в 1 варианте? Может оказаться, что одного просмотра достаточно или при дальнейшем просмотре элементы массива уже не меняются местами, т. е массив уже отсортирован. Тогда целесообразно ввести логическую переменную (флаг), и присваивать ей значение истина в случае, если замена происходила хотя бы один раз. Если значением этой переменной останется ложь, то просмотры необходимо прекратить.
const N=10; {Количество элементов массива} var a: array[1. . N] of integer; {массив} i: integer; {счётчик для цикла} f: boolean; {Признак наличия неупорядоченных пар} c: integer; {Переменная для промежуточного хранения} begin for i: =1 to N do read(a[i]); repeat f: =false; {Пока неупорядоченных пар не было} for i: =1 to N-1 do {Просматриваем все пары рядом стоящих элементов} begin if a[i]>a[i+1] then {Если пара стоит в неправильном порядке} begin f: =true; {Есть неупорядоченная пара} c: =a[i]; a[i]: =a[i+1]; a[i+1]: =c; {Меняем местами элементы массива} end; until not f; {Ждём, пока не исчезнут все неупорядоченные пары} for i: =1 to N do write(a[i]: 5); end.
3 вариант метода «пузырька» (усовершенствованный метод) Фрагмент программы for i: =1 to N-1 do for j: =i+1 to N do if A[i]>A[j] then begin T: =A[i]; A[i]: =A[j]; A[j]: =T; end;
Сортировка выбором Первое место в массиве должен занять минимальный элемент массива, второе – наименьший из всех остальных, третье – наименьший из оставшихся и т. д. Последовательность действий: 1. Определить минимальный элемент массива 2. Поменять его местами с первым 3. Определить минимальный среди оставшихся 4. Поменять местами со вторым и т. д.
Program Pr 2; Const N=10; Var A: array [1. . N] of real; min: real; i, t, k: integer; Begin { блок ввода массива написать самостоятельно} For i: =1 to N-1 do Begin min: =A[i]; t: =i; for k: =i+1 to N do if min>A[k] then begin min: =A[k]; t: =k end; A[t]: =A[i]; A[i]: =min; End; {Вывод массива написать самостоятельно} end.
Сортировка вставками Создается новый массив, в который мы последовательно вставляем элементы из исходного массива так, чтобы новый массив был упорядоченным.
• Это изящный и простой для понимания метод. Вот в чем его суть: создается новый массив, в который мы последовательно вставляем элементы из исходного массива так, чтобы новый массив был упорядоченным. Вставка происходит следующим образом: в конце нового массива выделяется свободная ячейка, далее анализируется элемент, стоящий перед пустой ячейкой (если, конечно, пустая ячейка не стоит на первом месте), и если этот элемент больше вставляемого, то подвигаем элемент в свободную ячейку (при этом на том месте, где он стоял, образуется пустая ячейка) и сравниваем следующий элемент. Так мы прейдем к ситуации, когда элемент перед пустой ячейкой меньше вставляемого, или пустая ячейка стоит в начале массива. Помещаем вставляемый элемент в пустую ячейку. Таким образом, по очереди вставляем все элементы исходного массива. Очевидно, что если до вставки элемента массив был упорядочен, то после вставки перед вставленным элементом расположены все элементы, меньшие его, а после — большие. Так как порядок элементов в новом массиве не меняется, то сформированный массив будет упорядоченным после каждой вставки. А значит, последней вставки мы получим упорядоченный исходный массив.
{Фрагмент программы, сортировка вставками} For i: =1 to N do Begin j: =i; While (j>1)and(B[j-1]>A[i]) do Begin B[j]: =B[j-1]; j: =j-1; End; B[j]: =A[i]; End;
• Данную сортировку можно реализовать и без дополнительного массива В, если сортировать массив А сразу при считывании, т. е. осуществлять вставку нового элемента в массив А.
Метод быстрой сортировки Алгоритмы сортировки массивов методом «пузырька» , «вставками» , «выбором» и другие имеют квадратичную сложность О(n²). Но, существуют методы быстрой сортировки массивов. Например метод C. A. R. Hoare, разработанный в 1960 году. Суть алгоритма: число операций перемены местоположений элементов внутри массива значительно сократится, если менять местами далеко стоящие друг от друга элементы. Для этого выбирается для сравнения один элемент х, отыскивается слева первый элемент, который не меньше х, а справа первый элемент, который не больше х. Найденные элементы меняются местами. После первого же прохода все элементы, которые меньше х, будут стоять слева от х, а все элементы, которые больше х, - справа от х. С двумя половинами массива поступают точно также. Продолжая деление этих половин до тех пор пока не останется в них по 1 элементу. Быстрая сортировка (англ. Quick sort), в среднем имеет сложность O(2 n ln n), однако в худшем случае (когда на каждом шаге массив делится на две части, одна из которых состоит из одного элемента) требуется O(n 2) обменов.
program Quitsort; uses crt; Const N=10; Type Mas=array[1. . n] of integer; var a: mas; k: integer; function Part(l, r: integer): integer; var v, i, j, b: integer; begin V: =a[r]; I: =l-1; j: =r; repeat dec(j) until (a[j]<=v) or (j=i+1); repeat inc(i) until (a[i]>=v) or (i=j-1); b: =a[i]; a[i]: =a[j]; a[j]: =b; until i>=j; a[j]: =a[i]; a[i]: = a[r]; a[r]: =b; part: =i; end; procedure Quick. Sort(l, t: integer); var i: integer; begin if l
Быстрая сортировка • Выбор значения разбиения можно сделать двумя способами. Это значение можно выбирать случайным образом или путем усреднения небольшого числа значений, выбранных из массива. Для оптимальной сортировки требуется выбрать значение, которое будет находиться в точности посередине всех элементов. Однако, для большинства наборов данных это сделать нелегко, даже в худшем случае, когда выбирается одно из экстремальных значений, быстрая сортировка работает достаточно хорошо. • В приводимом алгоритме быстрой сортировки в качестве значения разбиения используется среднее значение. Хотя такой подход не всегда является наилучшим, он достаточно прост и сортировка будет выполняться правильно.
Существуют ли более эффективные сортировки, имеющие, например, линейную сложность? • Да, для некоторых особых случаев существуют. Например, если известно, что все значения исходного массива находятся в интервале от 1 до некоторого значения MAX, можно использовать сортировку подсчетом. 18
• Для этого выделяется дополнительный массив счетчиков цел C[1: MAX] который предварительно обнуляется: нц для i от 1 до MAX C[i]: = 0 кц • Затем в цикле проходим весь массив с данными, и для каждого элемента A[i] увеличиваем счетчик C[A[i]]. Например, если A[i]=20, счетчик C[20] увеличивается на 1. После окончания цикла в каждом счетчике C[i] находится количество значений исходного массива, равных i. нц для i от 1 до n C[A[i]]: = C[A[i]] + 1 кц 19
Теперь остается расставить их в массиве A в нужном количестве. Например. Если C[20]=5, а значений, меньших 20, нет, в массив A записывается последовательно 5 значений, равных 20: k: = 1 нц для i от 1 до MAX нц для j от 1 до C[i] A[k]: = i k: = k + 1 кц кц 20


