Скачиваний:
79
Добавлен:
02.05.2014
Размер:
248.32 Кб
Скачать

Примеры программ

Чтобы облегчить сравнение различных алгоритмов сортировки, программа Sort на диске с примерами демонстрирует большинство алгоритмов, описанных в этой главе. Сортировка позволяет задать число сортируемых элементов, их максимальное значение, и порядок расположения элементов - прямой, обратный или расположение в случайном порядке. Программа создает список случайно расположенных чисел в формате long и сортирует его, используя выбранный алгоритм. Вначале сортируйте короткие списки, пока не определите, насколько быстро ваш компьютер может выполнять операции сортировки. Это особенно важно для медленных алгоритмов сортировки вставкой, сортировки вставкой с использованием связного списка, сортировки выбором, и пузырьковой сортировки.

Некоторые алгоритмы перемещают большие блоки памяти. Например, алгоритм сортировки вставкой перемещает элементы списка для того, чтобы можно было вставить новый элемент в середину списка. Для перемещения элементов программе, написанной на Visual Basic, приходится использовать цикл For. Следующий код показывает, как сортировка вставкой перемещает элементы с List(j) до List(max_sorted) для того, чтобы освободить место под новый элемент в позиции List(j):

For k = max_sorted To j Step -1

List(k + 1) = List(k)

Next k

List(j) = next_num

Интерфейс прикладного программирования системы Windows включает две функции, которые позволяют намного быстрее выполнять перемещение блоков памяти. Программы, скомпилированные 16‑битной версией компилятора Visual Basic 4, могут использовать функцию hmemcopy. Программы, скомпилированные 32‑битными компиляторами Visual Basic 4 и 5, могут использовать функцию RtlMoveMemory. Обе функции принимают в качестве параметров конечный и исходный адреса и число байт, которое должно быть скопировано. Следующий код показывает, как объявлять эти функции в модуле .BAS:

#if Win16 Then

Declare Sub MemCopy Lib "Kernel" Alias _

"hmemcpy" (dest As Any, src As Any, _

ByVal numbytes As Long)

#Else

Declare Sub MemCopy Lib "Kernel32" Alias _

"RtlMoveMemory" (dest As Any, src As Any, _

ByVal numbytes As Long)

#EndIf

Следующий фрагмент кода показывает, как сортировка вставкой может использовать эти функции для копирования блоков памяти. Этот код выполняет те же действия, что и цикл For, приведенный выше, но делает это намного быстрее:

If max_sorted >= j Then _

MemCopy List(j + 1), List(j), _

Len(next_num) * (max_sorted - j + 1)

List(j) = next_num

Программа FastSort на диске с примерами аналогична программе Sort, но она использует функцию MemCopy для ускорения работы некоторых алгоритмов. В программе FastSort алгоритмы, использующие функцию MemCopy, выделены синим цветом.

Сортировка выбором

Сортировка выбором (selectionsort) — простой алгоритм со сложность порядка O(N2). Идея состоит в поиске наименьшего элемента в списке, который затем меняется местами с элементом на вершине списка. Затем находится наименьший элемент из оставшихся, и меняется местами со вторым элементом. Процесс продолжается до тех пор, пока все элементы не займут свое конечное положение.

Public Sub Selectionsort(List() As Long, min As Long, max As Long)

Dim i As Long

Dim j As Long

Dim best_value As Long

Dim best_j As Long

For i = min To max - 1

‘ Найти наименьший элемент из оставшихся.

best_value = List(i)

best_j = i

For j = i + 1 To max

If List(j) < best_value Then

best_value = List(j)

best_j = j

End If

Next j

‘ Поместить элемент на место.

List(best_j) = List(i)

List(i) = best_value

Next i

End Sub

При поиске I-го наименьшего элемента, алгоритму приходится перебрать N-I элементов, которые еще не заняли свое конечное положение. Время выполнения алгоритма пропорционально N + (N - 1) + (N - 2) + … + 1, или порядка O(N2).

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

If list(j) < best_value Then

best_value = list(j)

best_j = j

End If

Если первоначально список отсортирован в обратном порядке, условие list(j) < best_value выполняется большую часть времени. Например, при первом проходе оно будет истинно для всех элементов, поскольку каждый элемент меньше предыдущего. Алгоритм будет многократно выполнять строки с оператором If, что приведет к некоторому замедлению работы алгоритма.

Это не самый быстрый алгоритм из числа описанных в главе, но он чрезвычайно прост. Это не только облегчает его разработку и отладку, но и делает сортировку выбором достаточно быстрой для небольших задач. Многие другие алгоритмы настолько сложны, что они сортируют очень маленькие списки медленнее.