
- •Тема 3б. Улучшенные методы сортировки массивов
- •Из предыдущей лекции мы знаем, что
- •Улучшенные методы сортировки эффективность О(n log2n)
- •Идея метода Шелла
- •Идея пирамидальной сортировки
- •Сортировка с помощью дерева поиска
- •Сортировка слиянием
- •Напомним, что тип массива записей введен следующим образом
- •Процедура слияния двух отсортированных
- •Трассировка слияния
- •Рекурсивное разбиение на подзадачи
- •Рекурсивная процедура сортировки слиянием
- •Описание класса
- •Трассировка сортировки слиянием
- •Метод разделения Хоара
- •Процедура разделения
- •Трассировка разделения
- •Рекурсивное разделение на подзадачи
- •Трассировка
- •Нерекурсивный вариант (начало)
- •Нерекурсивный вариант (продолжение)
- •Рекомендации
- •Контрольные вопросы
- •Задачи на экзамен
- ••unit Unit2;
- ••implementation
- ••Procedure Tob.SortSlip;
- ••Procedure SrSL(L,R:word);
- ••procedure TForm1.Button1Click(Sender: TObject);
- •Обработка события «Изменение окна Edit3»
- •Пример оформления экзаменационной задачи
- •Задачи на экзамен
- ••unit Unit2;
- ••implementation
- ••Procedure Tob.QuickSort;
- ••unit Unit1;
- •Обработка события «Изменение окна Edit3»
- •Пример оформления экзаменационной задачи
- •Конец темы 3
Трассировка
• |
|
8 6 |
4 |
3 2 |
5 |
1 |
x=3 |
|
• |
Первое разделение |
|
|
|
|
|||
• |
|
1 2 |
3 |
4 6 |
5 |
8 |
i=4 |
j=3 |
• |
1 |
2 3 |
|
4 |
6 |
5 |
8 |
|
• |
Второе разделение |
|
|
|
|
|||
• |
|
|
|
|
4 5 6 8 i=6 |
j=5 |
||
• |
|
|
|
4 5 |
|
6 8 |
|
07/02/19 |
22 |
Нерекурсивный вариант (начало)
•Procedure QuickSort(Var a:mas;n:Word);//nMr
•const M=12;
•Var i,j,L,R:Word; x:Tk; w:Tzp;
•s:0..M;
•stak:array[1..M] of record L,R:word end;
•begin
• |
s:=1; stak[1].L:=1; stak[1].R:=n; |
•Repeat //выбор из Steka последнего запроса
• |
L:=stak[s].L; R:=stak[s].R; s:=s-1; |
• |
Repeat |
• |
i:=L; j:=R; x:=a[L+Rаndom(R-L+1)].k; |
• |
Repeat //разделение a[L]...a[R] |
•While a[i].k<x do i:=i+1;
•While a[j].k>x do j:=j-1;
•if i<=j then begin
•w:=a[i];a[i]=a[j];a[j]:=w;i=i+1;j=j-1
• |
|
end; |
• |
until i>j; |
|
|
07/02/19 |
23 |
Нерекурсивный вариант (продолжение)
• if j-L<R-i then //какая половина длинее?
•begin
• |
if i<R then //запись в Stak запроса из правой части |
•begin s:=s+1; stak[s].L:=i; stak[s].R:=R; end
• |
R:=j; //продолж сорт левой части |
•end //теперь L и R ограничивают левую часть
• else
•begin
•if L<j then//запись в stak запроса из левой части
•begin s:=s+1;stak[s].L:=L;stak[s].R:=j end
• |
L:=I //продолж сорт правой части |
•end;
• |
until L>=R;//конец разделения очередной части |
•until s=0;//stak пуст
•End;//QuickSort.
07/02/19 |
24 |
Рекомендации
Для повышения устойчивости Хоар рекомендует выбирать «средний» элемент случайным образом:
|
x:=a[L+Random(R-L+1)].k; |
Метод быстрой сортировки «не любит» массивов, имеющих много одинаковых элементов, а также больших отсортированных участков.
Сравнение методов сортировок показывает, что при n>100 наихудшим является метод пузырька, метод QuickSort в 2-3 раза эффективнее, чем HeapSort, и в 3-7 раз чем метод Шелла.
Метод сортировки слиянием сравним по времени с QuickSort и избавлен от основных его недостатков (ему безразлично как изначально расположены элементы),
однако требует значительных затрат памяти. Поэтому он обычно используется для внешних сортировок (файлов, стеков).
07/02/19 |
25 |
Контрольные вопросы
В чем идея метода Шелла
Изложите идею пирамидальной сортировки
Изложите алгоритм сортировки слиянием на конкретном примере
Изложите алгоритм метода быстрой сортировки Хоара на конкретном примере
Дайте сравнительную характеристику эффективности методов прямой и быстрой
сортировок. |
26 |
07/02/19 |
Задачи на экзамен
Ввести массив записей {a[i].f, a[i].k} (f -
фамилия; к - учетный номер) из TstringGrid1, отсортировать по ключу к и выдать в TStringGrid2.
Алгоритм сортировки по методу слияния в виде рекурсивной процедуры оформить в отдельный модуль Unit2 как метод класса
07/02/19 |
27 |
•unit Unit2;
•interface
•Type
•Tinf=string[4];
•Tkey=word;
•Tzp=record
• |
zp:Tinf; |
• |
k:Tkey; |
• |
end; |
•mas=array[1..1] of Tzp;
•Tmas=^mas;
Класс сортировки слиянием
• |
Tob=class |
|
• |
a:Tmas; |
|
• |
n:word; |
|
• |
constructor create(n0:word); |
|
• |
Procedure SortSlip; |
|
• |
destructor Free; |
|
• |
end; |
28 |
|
07/02/19 |
•implementation
•constructor Tob.create(n0:word);
•begin
•inherited create;
•n:=n0;
•getmem(a,n0*sizeof(Tzp));
•end;
•destructor Tob.Free;
•begin
• Freemem(a,n*sizeof(Tzp));
•end;
07/02/19 |
29 |
•Procedure Tob.SortSlip;
•Procedure Slip(L,m,R:word);
•Var c: Tmas; i,j,k:word;
•begin
•getmem(C,n*sizeof(Tzp));
•i:=L; k:=1; j:=m+1;
•while (i<=m) and (j<=R) do
•if a[i].k<a[j].k
•then begin c[k]:=a[i]; Inc(i); Inc(k) end
•else begin c[k]:=a[j]; Inc(j); Inc(k) end;
•while i<=m do
•begin c[k]:=a[i]; Inc(i); inc(k) end;
•while j<=R do
•begin c[k]:=a[j]; Inc(j); Inc(k) end;
•k:=0;
•for i:=L to R do
•begin Inc(k); a[i]:=c[k] end;
•Freemem(c,n*sizeof(Tzp));
•end;
07/02/19 |
30 |
•Procedure SrSL(L,R:word);
•var m:word;
•begin
•if L<>R then begin
• |
m:=(L+R) div 2 |
• |
SrSL(L,m); |
• |
SrSL(m+1,R); |
• |
Slip(L,m,R); |
• |
end; |
•end;
•begin
•SrSL(1,n)
•end;
07/02/19 |
31 |