Лекции.Орг


Поиск:




Категории:

Астрономия
Биология
География
Другие языки
Интернет
Информатика
История
Культура
Литература
Логика
Математика
Медицина
Механика
Охрана труда
Педагогика
Политика
Право
Психология
Религия
Риторика
Социология
Спорт
Строительство
Технология
Транспорт
Физика
Философия
Финансы
Химия
Экология
Экономика
Электроника

 

 

 

 


Сортировка списков. Список может быть отсортирован, если определено отношение упорядочения меж­ду элементами в списке




Список может быть отсортирован, если определено отношение упорядочения меж­ду элементами в списке. Для целей этого описания предполагается, что существует следующее отношение упорядочения: gt{ х, Y)

которое означает, что х больше Y, независимо от того, какой смысл вкладывается в понятие "больше". Если рассматриваемыми элементами являются числа, то отноше­ние дг может быть, по всей вероятности, определено следующим образом: gt (X, Y): - Х>У.

Если же элементы представляют собой атомы, то отношение gt может соответст­вовать лексикографическому упорядочению, например, определенному как:

gtl X, Y):- Х@>¥,

Напомним, что это отношение упорядочивает также составные термы. Предполо­жим, что терм

sort! List, Sorted)

обозначает отношение, где List является списком элементов, a Sorted — списком тех же элементов, отсортированным в порядке возрастания в соответствии с отноше-


нием gt. В данной главе рассматриваются три определения этого отношения на язы­ке Prolog, которые основаны на разных принципах сортировки списков. Ниже опи­сан первый принцип.

Для сортировки списка List необходимо выполнить следующее:

■ найти в списке List два смежных элемента, X и Y, таких, что отношение gt { X, У] принимает истинное значение, и поменять местами х и Y в списке List, получив при этом список Listl; после этого отсортировать Listl;

■ если в списке List нет ни одной пары смежных элементов, X и Y, таких, что отношение gt (X, Y) принимает истинное значение, то список List уже от­сортирован.

Результатом перестановки местами двух элементов, X и Y, которые занимают не­правильное положение по отношению друг к другу, является то, что после этой пере­становки новый список в большей степени напоминает отсортированный список. По­сле достаточного количества перестановок в конечном итоге должно быть достигнуто такое состояние, в котором все элементы занимают правильные положения. Такой принцип сортировки известен под названием пузырьковой сортировки (bubble sort). Поэтому соответствующей процедуре Prolog, приведенной ниже, будет присвоено на­звание bubblesort.

bubblesort (List, Sorted);-

swap(List, Listl),!, i Есть ли допустимая перестановка в списке List?

bubblesort (Listl, Sorted).

bubblesort (Sorted, sorted). % В противном случае список уже отсортирован

s»ap([X, Y | Rest], [y, X | Rest]):- * Поменять местами первые два элемента

gt(X, X).

swapf [Z I Rest], [Z 1 Restl]):- % Поменять местами элемента в хвосте

swap; Rest, Restl).

Еще одним простым алгоритмом сортировки является сортировка вставкой, кото­рая основана на описанном ниже принципе.

Чтобы отсортировать непустой список, L. [X | Т], необходимо выполнить следующее.

1. Отсортировать хвост Т списка L.

2. Вставить голову X списка L в отсортированный хвост списка, в такую позицию, чтобы результирующий список оставался отсортированным. В результате будет получен весь отсортированный список.

Такую постановку задачи можно перевести на язык Prolog в виде следующей процедуры insert sort:

insertsort ([],П>-

insertsort! [X I Tail], Suited):-

insertsort (Tail, SortedTa.il), % Отсортировать хвост списка

insert! X, SortedTail, Sorted). Ъ Вставить х в надлежащем месте

insert t x, [Y! Sorted], [Y; Sortedl]):-

gt< x, Y),!,

insertf X, Sorted, Sortedl). insert! x, Sorted, [X I Sorted]).


Глава Э. Операции со структурами данных



Процедуры сортировки bubblesorr и insertsort являются простыми, но неэф­фективными. Из этих двух процедур сортировка вставкой (insertsort)является бо­лее эффективной. По среднее время, необходимое для сортировки списка длиной п с помощью процедуры inserzsort, возрастает пропорционально г/. Поэтому для сор­тировки длинных списков предусмотрен гораздо более эффективный алгоритм сорти­ровки — quicksort. Он основан на следующем принципе, который иллюстрируется на рис. 9.1.

[5,3,7,8,1,4,7,61


i


удалить Х(Х = 51


[3,7,В,1,4,7,6]


           
 
 
 
 
     

разбиение

,'1!>(>;'-!И L

все элементы £ 5

[3,1,4]

ъ

сортировать

[1,3,4]

I


 

i не:n nmiMOHTbi >5
[7,8,7,6]  
1сортире
[ 6.7,7,8]

$


выполнить конкатенацию

V

1,3,4,5,6,7,7,8

Рис- 9Л Сортировки списка с помощью алгоритма

quicksort

Описание алгоритма quicksort приведено ниже.

Чтобы отсортировать непустой список L, необходимо выполнить следующие действия.

1. Удалить некоторый элемент X из списка L и разбить остаток L на два списка, называемые Small и Big, следующим образом: перенести все элементы списка L, которые больше X, в список Big, а все остальные — в список Small.

2. Отсортировать список Small, получив список SortedSmall.

3. Отсортировать список Big, получив список SortedBig.

4. Весь отсортированный список представляет собой конкатенацию списков

SortedSmall и [X | SortedBig}.

Если сортируемый список пуст, то результатом сортировки также является пус­той список. Реализация процедуры quicksort на языке Prolog приведена в листин-



Часть I. Язык Prolog


ре 9.1. Характерной особенностью этой реализации является то, что элемент X, уда­ляемый из списка L, всегда представляет собой голову списка L. Операция разбиения списка программируется в виде следующего отношения с четырьмя параметрами: split; X, L, Small, Big)

Сложность этого алгоритма, определяемая затратами времени на выполнение, за­висит от того, насколько удачно происходит разбиение сортируемого списка. Если список разбивается на два списка, имеющих приблизительно равную длину, то за­траты времени на выполнение этой процедуры сортировки пропорциональны п log л, где я — длина сортируемого списка. Если, вопреки ожиданиям, разбиение всегда приводит к тому, что один список становится больше другого, то затраты времени становятся пропорциональными . Но, к счастью, исследования показали, что сред­няя производительность процедуры quicksort ближе к наилучшему варианту, чем к наихудшему.

Программу, приведенную в листинге 9.1, можно дополнительно усовершенство­вать, применив лучшую реализацию операции конкатенации. Благодаря использова­нию представления списков в виде разностных пар, описанного в главе 8, операция конкатенации становится тривиальной. Для применения этой идеи в рассматривае­мой процедуре сортировки списки, применяемые в листинге 9.1, можно представить в виде пары списков в форме A-Z следующим образом;

SortedSmall представлен как A1-Z1 SortedBig представлен как A2-Z2

Л ИСТИ НГ 9.1. Процедура быстрой сортировки quicksort

?''qaic):sort7List,'soitedListr:........................

% сортироька списка List с применением алгоритма quicksort quicksort! [], []).

quick s SortedSmall 3, or [X tedSm,Ei3,. Sorted).

split (x, [ ], [ ], [ 1).

Split; X, [YITail], [ Y | Small], Big):-gt(x, Y),!, split! X, Tail, Small, Big).

Split! X, [Y|Tail), Small, [YjBigU:-split! X, Tail, Small, Big;.

Таким образом, конкатенация списков SortedSmall и [X | SortedBig] соответ­ствует конкатенации следующих пар:

А1 - Z1 и [X | А2] - Z2

Список, полученный в результате конкатенации, представляется с помощью сле­дующего выражения:

AI - Z2, 1 до Z2 - [X | А2]

Пустой список представлен любой парой Z-Z. В результате систематического вне­сения этих изменений в программу (см. листинг 9.1) получена более эффективная реализация процедуры quicksort, запрограммированная в виде quicksort2 в лис­тинге 9.2. В процедуре quicksort все еще используется обычное представление спи­сков, но сортировка фактически выполняется более эффективной процедурой


Глава Э. Операции со структурами данных



quicksort2, в которой применяется представление списков в виде разностных пар. Отношение между этими двумя процедурами выглядит следующим образом:

quicksort Г L, S!:-

quicksorts t L, S - I ]),

Листинг 9.2. Более эффективная реализация процедуры q u i c ks o rt с использованием представления списков в виде разностных пар; отношение s p l i t (x, List, small, Big) приведено в листинге 9.1

'■■ quicksort (List, SortedList):

сортировка списка List с применением алгоритма quicksort

quicksort': List, Sorted):-

quickscrt2 (list, Sorted - [)).

\ quicksort2 (List, SortedDiffList): сортировка списка List,- результат % представлен как разностный список

quicksort2 (J.l, Z - Z}.

quicksort2([У. Tail), 7U - Z2):-split(X, Tail, Small, Big), quicksorts! Small, Al -.:■: A2 ]), quicksort2 I eiq, A2 - Z2).

Упражнения

9.1. Напишите процедуру для слияния двух отсортированных списков и получения
третьего списка, например, следующим образом:

?- raerqef [2,5,6,6,8], [1,3,5,9], L). L = [1,2,3,3,5,6, "3,6,5]

9.2. Различие между программами сортировки, приведенными в листингах 9.1 и 9.2, состоит в том, что используются иные представления списков, — в по­следней применяются разностные списки. Процедура преобразования обычных списков в разностные является простой и может выполняться механически. В качестве упражнения систематически внесите соответствующие изменения в программу, приведенную в листинге 9.1, чтобы преобразовать ее в программу, которая показана в листинге 9.2.

9.3. Рассматриваемая программа quicksort обнаруживает низкую эффективность, если сортируемый список уже полностью отсортирован или почти отсортиро­ван. Объясните, с чем это связано.

9.4. Еще один перспективный принцип сортировки списков, позволяющий устра­нить указанный выше недостаток процедуры quicksort, основан на том, что список делится на части, после чего меньшие списки сортируются, а затем эти отсортированные меньшие списки сливаются. В соответствии с этим, чтобы от­сортировать список _, необходимо выполнить следующее:

 

• разделить список: на два списка, L1 и L2, приблизительно равной длины;

• отсортировать L1 и L2, получив списки S1 и S2;

• выполнить слияние списков S1 и S2 и получить отсортированный список L.

Такой алгоритм известен под названием алгоритма сортировки - слияния. Реализуйте алгоритм сортировки-слияния и сравните эффективность получен­ной программы с программой quicksort.

196 Часть I. Язык Prolog






Поделиться с друзьями:


Дата добавления: 2015-10-01; Мы поможем в написании ваших работ!; просмотров: 616 | Нарушение авторских прав


Поиск на сайте:

Лучшие изречения:

Начинайте делать все, что вы можете сделать – и даже то, о чем можете хотя бы мечтать. В смелости гений, сила и магия. © Иоганн Вольфганг Гете
==> читать все изречения...

2335 - | 2134 -


© 2015-2025 lektsii.org - Контакты - Последнее добавление

Ген: 0.011 с.