скачать рефераты
  RSS    

Меню

Быстрый поиск

скачать рефераты

скачать рефератыРеферат: VB, MS Access, VC++, Delphi, Builder C++ принципы(технология), алгоритмы программирования

Сортировка подсчетом начинается с создания массива для подсчета числа элементов, имеющих определенное значение. Если значения находятся в диапазоне между min_value и max_value, алгоритм создает массив Counts с нижней границей min_value и верхней границей max_value. Если используется массив из предыдущего прохода, необходимо обнулить значения его элементов. Если существует M значений элементов, массив содержит M записей, и время выполнения этого шага порядка O(M).

For i = min To max

    Counts(List(i)) = Counts(List(i)) + 1

Next i

В конце концов, алгоритм обходит массив Counts, помещая соответствующее число элементов в отсортированный массив. Для каждого значения i между min_value и max_value, он помещает Counts(i) элементов со значением i в массив. Так как этот шаг помещает по одной записи в каждую позицию в массиве, он требует порядка O(N) шагов.

new_index = min

For i = min_value To max_value

    For j = 1 To Counts(i)

        sorted_list(new_index) = i

        new_index = new_index + 1

    Next j

Next i

======255

Алгоритм целиком требует порядка O(M)+O(N)+O(N)=O(M+N) шагов. Если M мало по сравнению с N, он выполняется очень быстро. Например, если M<N, то O(M+N)=O(N), что довольно быстро. Если N=100.000 и M=1000, то M+N=101.000, тогда как N*log(N)=1,6 миллиона. Шаги, выполняемые алгоритмом сортировки подсчетом, также относительно просты по сравнению с шагами быстрой сортировки. Все эти факты объединяются, обеспечивая вместе невероятно высокую скорость выполнения сортировки подсчетом.

С другой стороны, если M больше, чем O(N*log(N)), тогда O(M+N) будет больше, чем O(N*log(N)). В этом случае сортировка подсчетом может оказаться медленнее, чем алгоритмы со сложностью порядка O(N*log(N)), такие как быстрая сортировка. В одном из тестов быстрая сортировка 1000 элементов со значениями от 1 до 500.000 потребовал 0,054 сек, в то время как сортировка подсчетом потребовала 1,76 секунд.

Сортировка подсчетом опирается на тот факт, что значения данных — целые числа, поэтому этот алгоритм не может просто сортировать данные других типов. В Visual Basic нельзя создать массив с границами от AAA до ZZZ.

Ранее в этой главе в разделе «объединение и сжатие ключей» было продемонстрировано, как можно кодировать строковые данные при помощи целых чисел. Если вы может закодировать данные при помощи данных типа Integer или Long, вы все еще можете использовать сортировку подсчетом.

Блочная сортировка

Как и сортировка подсчетом, блочная сортировка (bucketsort) не использует операций сравнения элементов. Этот алгоритм использует значения элементов для разбиения их на блоки, и затем рекурсивно сортирует полученные блоки. Когда блоки становятся достаточно малыми, алгоритм останавливается и использует более простой алгоритм типа сортировки выбором для завершения процесса.

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

Для деления списка на блоки, алгоритм предполагает, что значения данных распределены равномерно, и распределяет элементы по блокам равномерно. Например, предположим, что данные имеют значения в диапазоне от 1 до 100 и алгоритм использует 10 блоков. Алгоритм помещает элементы со значениями 1‑10 в первый блок, со значениями 11‑20 — во второй, и т.д. На рис. 9.12 показан список из 10 элементов со значениями от 1 до 100, которые расположены в 10 блоках.

@Рис. 9.12. Расположение элементов в блоках.

=======256

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

На практике, распределение данных обычно не является равномерным. В некоторые блоки попадает больше элементов, в другие меньше. Тем не менее, если распределение в целом близко к равномерному, то в каждом из блоков окажется лишь небольшое число элементов.

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

Блочная сортировка с применением связного списка

Реализовать алгоритм блочной сортировки на Visual Basic можно различными способами. Во-первых, можно использовать в качестве блоков связные списки. Это облегчает перемещение элементов между блоками в процессе работы алгоритма.

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

Public Sub LinkBucketSort(ListTop As ListCell)

Dim count As Long

Dim min_value As Long

Dim max_value As Long

Dim Value As Long

Dim item As ListCell

Dim nxt As ListCell

Dim bucket() As New ListCell

Dim value_scale As Double

Dim bucket.num As Long

Dim i As Long

    Set item = ListTop.NextCell

    If item Is Nothing Then Exit Sub

    ' Подсчитать элементы и найти значения min и max.

    count = 1

    min_value = item.Value

    max_value = min_value

    Set item = item.NextCell

    Do While Not (item Is Nothing)

        count = count + 1

        Value = item.Value

        If min_value > Value Then min_value = Value

        If max_value < Value Then max_value = Value

        Set item = item.NextCell

    Loop

    ' Если min_value = max_value, значит, есть единственное

    ' значение, и список отсортирован.

    If min_value = max_value Then Exit Sub

    ' Если в списке не более, чем CutOff элементов,

    ' завершить сортировку процедурой LinkInsertionSort.

    If count <= CutOff Then

        LinkInsertionSort ListTop

        Exit Sub

    End If

    ' Создать пустые блоки.

    ReDim bucket(1 To count)

    value_scale = _

    CDbl(count - 1) / _

    CDbl(max_value - min_value)

    ' Разместить элементы в блоках.

    Set item = ListTop.NextCell

    Do While Not (item Is Nothing)

        Set nxt = item.NextCell

        Value = item.Value

        If Value = max_value Then

           bucket_num = count

        Else

           bucket_num = _

               Int((Value - min_value) * _

                   value_scale) + 1

        End If

        Set item.NextCell = bucket (bucket_num).NextCell

        Set bucket(bucket_num).NextCell = item

        Set item = nxt

    Loop

    ' Рекурсивная сортировка блоков, содержащих

    ' более одного элемента.

    For i = 1 To count

        If Not (bucket(i).NextCell Is Nothing) Then _

           LinkBucketSort bucket(i)

    Next i

    ' Объединить отсортированные списки.

    Set ListTop.NextCell = bucket(count).NextCell

    For i = count - 1 To 1 Step -1

        Set item = bucket(i).NextCell

        If Not (item Is Nothing) Then

           Do While Not (item.NextCell Is Nothing)

               Set item = item.NextCell

           Loop

           Set item.NextCell = ListTop.NextCell

           Set ListTop.NextCell= bucket(i).NextCell

        End If

    Next i

End Sub

=========257-258

Эта версия блочной сортировки намного быстрее, чем сортировка вставкой с использованием связных списков. В тесте на компьютере с процессором Pentium с тактовой частотой 90 МГц сортировке вставкой потребовалось 6,65 секунд для сортировки 2000 элементов, блочная сортировка заняла 1,32 секунды. Для более длинных списков разница будет еще больше, так как производительность сортировки вставкой порядка O(N2).

Блочная сортировка на основе массива

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

Public Sub ArrayBucketSort(List() As Long, Scratch() As Long, _

    min As Long, max As Long, NumBuckets As Long)

Dim counts() As Long

Dim offsets() As Long

Dim i As Long

Dim Value As Long

Dim min_value As Long

Dim max_value As Long

Dim value_scale As Double

Dim bucket_num As Long

Dim next_spot As Long

Dim num_in_bucket As Long

    ' Если в списке не более чем CutOff элементов,

    ' закончить сортировку процедурой SelectionSort.

    If max - min + 1 < CutOff Then

        Selectionsort List(), min, max

        Exit Sub

    End If

    ' Найти значения min и max.

    min_value = List(min)

    max_value = min_value

    For i = min + 1 To max

        Value = List(i)

        If min_value > Value Then min_value = Value

        If max_value < Value Then max_value = Value

    Next i

    ' Если min_value = max_value, значит, есть единственное

    ' значение, и список отсортирован.

    If min_value = max_value Then Exit Sub

    ' Создать пустой массив с отсчетами блоков.

    ReDim counts(l To NumBuckets)

    value_scale = _

        CDbl (NumBuckets - 1) / _

        CDbl (max_value - min_value)

    ' Создать отсчеты блоков.

    For i = min To max

        If List(i) = max_value Then

           bucket_num = NumBuckets

        Else

           bucket_num = _

               Int((List(i) - min_value) * _

                   value_scale) + 1

        End If

        counts(bucket_num) = counts(bucket_num) + 1

    Next i

    ' Преобразовать отсчеты в смещение в массиве.

    ReDim offsets(l To NumBuckets)

    next_spot = min

    For i = 1 To NumBuckets

        offsets(i) = next_spot

        next_spot = next_spot + counts(i)

    Next i

    ' Разместить значения в соответствующих блоках.

    For i = min To max

        If List(i) = max_value Then

           bucket_num = NumBuckets

        Else

           bucket_num = _

               Int((List(i) - min_value) * _

                   value_scale) + 1

        End If

        Scratch (offsets (bucket_num)) = List(i)

        offsets(bucket_num) = offsets(bucket_num) + 1

    Next i

    ' Рекурсивная сортировка блоков, содержащих

    ' более одного элемента.

    next_spot = min

    For i = 1 To NumBuckets

        If counts(i) > 1 Then ArrayBucketSort _

           Scratch(), List(), next_spot, _

           next_spot + counts(i) - 1, counts(i)

        next_spot = next_spot + counts(i)

    Next i

    ' Скопировать временный массив назад в исходный список.

    For i = min To max

        List(i) = Scratch(i)

    Next i

End Sub

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

Новую версию также можно сделать еще быстрее, используя функцию API MemCopy для копирования элементов из временного массива обратно в исходный список. Эта усовершенствованную версию алгоритма демонстрирует программа FastSort.

===========259-261

Резюме

В таб. 9.4 приведены преимущества и недостатки алгоритмов сортировки, описанных в этой главе, из которых можно вывести несколько правил, которые могут помочь вам выбрать алгоритм сортировки.

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

*      если вам нужно быстро реализовать алгоритм сортировки, используйте быструю сортировку, а затем при необходимости поменяйте алгоритм;

*      если более 99 процентов списка уже отсортировано, используйте пузырьковую сортировку;

*      если список очень мал (100 или менее элементов), используйте сортировку выбором;

*      если значения находятся в связном списке, используйте блочную сортировку на основе связного списка;

*      если элементы в списке — целые числа, разброс значений которых невелик (до нескольких тысяч), используйте сортировку подсчетом;

*      если значения лежат в широком диапазоне и не являются целыми числами, используйте блочную сортировку на основе массива;

*      если вы не можете тратить дополнительную память, которая требуется для блочной сортировки, используйте быструю сортировка

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

@Таблица 9.4. Преимущества и недостатки алгоритмов сортировки

=========263

Глава 10. Поиск

После того, как список элементов отсортирован, может понадобиться найти определенный элемент в списке. В этой главе описаны некоторые алгоритмы для поиска элементов в упорядоченных списках. Она начинается с краткого описания сортировки методом полного перебора. Хотя этот алгоритм выполняется не так быстро, как другие, метод полного перебора является очень простым, что облегчает его реализацию и отладку. Из‑за простоты этого метода, сортировка полным перебором также выполняется быстрее других алгоритмов для очень маленьких списков.

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

Затем в главе описан интерполяционный поиск. Так же, как и в методе двоичного поиска, исходный список при этом многократно разбивается на части. При использовании интерполяционного поиска, алгоритм делает предположения о том, где может находиться искомый элемент, поэтому он выполняется намного быстрее, если данные в списках распределены равномерно.

В конце главы обсуждаются методы следящего поиска. Применение этого метода иногда уменьшает время поиска в несколько раз.

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

Программа Search демонстрирует все описанные в главе алгоритмы. Введите значение элементов, которые должен содержать список, и затем нажмите на кнопку Make List (Создать список), и программа создаст список на основе массива, в котором каждый элемент больше предыдущего на число от 0 до 5. Программа выводит значение наибольшего элемента в списке, чтобы вы представляли диапазон значений элементов.

После создания списка выберите алгоритмы, которые вы хотите использовать, установив соответствующие флажки. Затем введите значение, которое вы хотите найти и нажмите на кнопку Search (Поиск), и программа выполнит поиск элемента при помощи выбранного вами алгоритма. Так как список содержит не все возможные элементы в заданном диапазоне значений, то вам может понадобиться ввести несколько различных значений, прежде чем одно из них найдется в списке.

Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48


Новости

Быстрый поиск

Группа вКонтакте: новости

Пока нет

Новости в Twitter и Facebook

  скачать рефераты              скачать рефераты

Новости

скачать рефераты

© 2010.