Главная страница
Навигация по странице:

  • 8.2. Сортировка методом “пузырька”

  • 8.2.1. Метод "пузырька" для массивов Самой простой сортировкой массивов является сортировка методом "пузырька". Рассмотрим для однозначности сортировку по убыванию

  • 8.2.2. Метод "пузырька" для структур

  • 8.3. Сортировка методом выбора

  • 8.4. Сортировка методом вставки

  • 8.5. Быстрая сортировка На практике применяется огромное количество методов сортировки массивов. Рассмотрим теперь более сложную сортировку, получившую на- звание быстрая сортировка.

  • Программирование на visual basic


    Скачать 1.19 Mb.
    НазваниеПрограммирование на visual basic
    Анкорvb.pdf
    Дата05.06.2021
    Размер1.19 Mb.
    Формат файлаpdf
    Имя файлаvb.pdf
    ТипУчебное пособие
    #214287
    страница11 из 17
    1   ...   7   8   9   10   11   12   13   14   ...   17
    A
    рабочего листа “Лист1”, подсчитать количество чисел равных максимальному значению.

    91
    Sub КоличествоМаксимальныхЧисел()
    Dim numb As Double, max As Double, n As Long, NMax As Long max = -1.7E+308 ' Это - ∞. Здесь получим максимальное значение
    NMax = 0 ' Число элементов равных максимальному
    Sheets(“Лист1”).Select ‘ Перейти на рабочий лист с именем Лист1
    Номер строки, с которой будем начинать считывать данные n = 1
    Do numb = Cells(n, 1) ‘ Считать число с ячейки n первого столбца
    Если в ячейки пусто выйти из цикла
    If numb = Empty Then Exit Do
    If numb > max Then
    'Если встретили число, которое больше предыдущих, то обнуляем
    'счетчик количества максимальных чисел и запоминаем значение ‘max
    NMax = 0: max = numb
    End If
    ' Если число равно максимальному значению, то счетчик
    ‘максимальных чисел увеличить на 1
    If numb = max Then NMax = NMax + 1 n = n + 1 ' Перейти к следующей строке
    Loop
    Debug.Print "Количество чисел, равных максимальному "; max; " = "; _
    NMax; " Всего чисел в столбце="; n-1
    End Sub
    8.1.3. В одномерном массиве случайных действительных чисел размер- ности N подсчитать количество элементов, которые меньше всех преды- дущих элементов.
    Sub КоличествоЭлементовМеньшихПредыдущих()
    Dim a() As Double, i As Integer, n As Integer, numb As Integer, _ j As Integer
    Sheets("Лист1").Select
    Range("a1:b100").Clear ‘ Очистить ячейки n = Val(InputBox("Введите N"))
    ReDim a(n) ‘ Создать динамический массив a
    Randomize Timer
    For i = 1 To n
    ' Заполнение массива случайными действительными числами
    ‘в диапазоне от 0 до 100
    a(i) = Rnd * 100 : Cells(i, 1) = a(i)
    Next i numb = 1
    Нумеруем элементы < всех предыдущих и выводим
    ' их номера во втором столбце
    Cells(1, 2) = numb
    For i = 2 To n
    For j = 1 To i - 1

    92
    If a(j) >= a(i) Then GoTo m
    Next j numb = numb + 1 : Cells(i, 2) = numb m: Next i
    MsgBox ("В данной последовательности " + Str(numb) + _
    " элементов меньших предыдущих")
    End Sub
    8.1.4. В одномерный массив
    A
    записать 30 целых положительных слу- чайных трехзначных чисел. Полученный массив вывести в первый столбец рабочего листа. В массиве
    A
    поменять местами элементы, стоящие на не- четном месте со следующими элементами, стоящими на четных местах.
    Полученный массив записать во второй столбец.
    Sub ИнверсияНеЧетныеНаЧетные()
    Const N = 30
    Dim a(N) As Integer, t As Integer, i As Integer
    Sheets("Лист1").Select : Range("A1:b100").Clear
    Randomize Timer
    For i = 1 To N
    ' Заполнение массива случайными трехзначными числами
    a(i) = 899 * Rnd + 100
    ' Вывод полученного массива в первый столбец
    Cells(i, 1) = a(i)
    Next i
    For i = 1 To N - 1 Step 2
    ' Перестановка двух соседних элементов массива местами
    t = a(i): a(i) = a(i + 1): a(i + 1) = t
    Next i
    ' Вывод во второй столбец полученного массива
    For i = 1 To N
    Cells(i, 2) = a(i)
    Next i
    End Sub
    8.1.5. В одномерный массив
    A
    записать 20 случайных действительных чисел в диапазоне от 100 до 10000. Поменять местами максимальный и минимальный элементы. В третий столбец вывести исходный массив, а в четвертый – полученный массив.
    Sub ИнверсияМаксимальныйНаМинимальный()
    Const N = 20
    Dim a(N) As Double, t As Double, i As Integer, imax As Integer, _ imin As Integer
    Sheets("Лист1").Select
    Randomize Timer
    ' Заполнение массива случайными числами в диапазоне (100,10000)
    For i = 1 To N
    ' Получить элементы массива с двумя знаками после запятой a(i) = Int((9900 * Rnd + 100) * 100) / 100

    93
    ' Вывод полученного массива в третий столбец
    Cells(i, 3) = a(i)
    Next i
    ' Номер максимального и минимального элементов imax = 1: imin = 1
    For i = 2 To N
    'Поиск месторасположения максимального и минимального
    ‘элементов
    If a(i) > a(imax) Then imax = i
    If a(i) < a(imin) Then imin = i
    Next i
    ' Обмен элементов местами
    t = a(imax): a(imax) = a(imin): a(imin) = t
    For i = 1 To N ‘ Вывод результата в 4 столбец
    Cells(i, 4) = a(i)
    Next i
    MsgBox ("Совершен обмен в строках " + Str(imin) + " и " + Str(imax))
    End Sub
    8.2. Сортировка методом “пузырька”
    Рассмотрим в начале сортировку числовых массивов по возрастанию или убыванию элементов.
    Дан числовой массив действительных или целых чисел. Элементы мас- сива обозначим: A
    1
    , A
    2
    , A
    3
    , A
    4
    , … , A
    N
    . Необходимо при помощи конечно- го числа перестановок пар элементов расставить элементы в порядке воз- растания или убывания. Т.е. чтобы выполнялись условия:
    A
    1
    ≥ A
    2
    ≥A
    3
    ≥A
    4
    ≥… ≥A
    N
    – для сортировки по убыванию и A
    1

    A
    2
    ≤A
    3
    ≤A
    4
    ≤… ≤A
    N
    – для сортировки по возрастанию.
    8.2.1. Метод "пузырька" для массивов
    Самой простой сортировкой массивов является сортировка методом "пузырька". Рассмотрим для однозначности сортировку
    по убыванию
    элементов. Для сортировки по возрастанию необходимо поменять знаки неравенства на противоположные. Смысл сортировки методом "пузырька" заключается в следующем.
    Начиная с первого элемента, сравниваем два соседних элемента i-тый и
    (i+1)-ый. Если A
    i+1
    > A
    i
    , то переставляем эти два элемента местами. И так до N-1-го элемента. В результате на место N-го элемента переместился са- мый малый элемент. Т.е. самый “легкий” элемент всплыл “наверх”. Затем повторяем эту же процедуру с 1-го до N-2-го элементов. В результате N-2- ой элемент становится на место. И так до тех пор, пока 2-ой элемент не станет на свое место. В этом случае первый элемент автоматически встал на свое место.
    1. i=1.
    2. j=1.

    94 3. Если A
    j+1
    > A
    j
    , то переставить их местами.
    4. j=j+1.
    5. Если j≤N-i, перейти на 3.
    6. i=i+1.
    7. Если i≤N-1, перейти на 2.
    В этом алгоритме используется двухмерный цикл. Первый (внешний) цикл с параметром цикла i изменяется от 1 (пункт 1) до N-1 (пункт 7). Вто- рой (внутренний цикл) с параметром цикла j изменяется от 1 (пункт 2) до
    N-i (пункт 5). Тело внутреннего цикла (пункт 3) выполняется (N-1) раз при i=1; (N-2) раза при i=2; …и 1 раз при i=N-1. Таким образом, общее число выполнения внутреннего цикла k, определяющее трудоемкость метода, равно N
    2
    /2. Значит, при увеличении N в 2 раза время сортировки увеличит- ся примерно в четыре раза.
    2
    )
    1
    (
    2 1
    )
    1
    (
    2
    N
    N
    N
    k



    +

    =
    На примере числового массива, состоящего из 6 элементов, рассмотрим данный алгоритм сортировки. Затененные элементы не участвуют в сорти- ровке на следующем шаге.
    7 1 8 3 6 9 Исходный массив
    7 8 3 6 9 1 1-ый шаг. 4 перестановки (1-8;1-3;1-6;1-9.)
    8 7 6 9 3 1 2-ый шаг. 3 перестановки (7-8;3-6;3-9)
    8 7 9 6 3 1 3-ий шаг. 1 перестановка (6-9)
    8 9 7 6 3 1 4-ый шаг. 1 перестановка (7-9)
    9 8 7 6 3 1 5-ый шаг. 1 перестановка (8-9)
    Ниже представлена подпрограмма, реализующая этот алгоритм.
    Sub СортировкаМассиваМетодомПузырька(a() As Double, N As Long)
    Dim t As Double, i As Long, j As Long
    For i = 1 To N - 1
    For j = 1 To N - i
    If a(j + 1) > a(j) Then ' Переставить j-тый и j+1-ый элементы t = a(j): a(j) = a(j + 1): a(j + 1) = t
    End If
    Next j, i
    End Sub
    Для отладки представленной подпрограммы напишем основную про- грамму, в которой заполним случайными числами массив
    a
    , выведем его в первый столбец рабочего листа “Лист3”, вызовем подпрограмму Сорти- ровкаМассиваМетодомПузырька, а результаты выведем в третий столбец.
    Sub ТестСортировкиМассиваМетодомПузырка()
    Const N = 20
    Dim a(N) As Double, i As Long
    Randomize Timer
    Sheets("Лист3").Select
    For i = 1 To N a(i) = Int(Rnd * 10000) / 100 ' Два знака после запятой

    95
    Cells(i, 1) = a(i)
    Next i
    Call СортировкаМассиваМетодомПузырька(a, N)
    For i = 1 To N
    Cells(i, 2) = a(i)
    Next i
    End Sub
    Часто возникает необходимость сортировать символьные массивы по алфавиту. В VB эта задача решается так же, как для числового массива.
    Только массив
    a
    и временную переменную
    t
    необходимо описать как пе- ременную типа String. Вместо типа String можно использовать более об- щий тип Variant.
    ' Сортировка символьного массива по алфавиту от А до Я
    Sub СортировкаСимвольногоМассиваМетодомПузырька(a As Variant, _
    N As Long)
    Dim t As String, i As Long, j As Long
    For i = 1 To N - 1
    For j = 1 To N - i
    If a(j + 1) < a(j) Then ' Переставить j-тый и j+1-ый элементы
    t = a(j): a(j) = a(j + 1): a(j + 1) = t
    End If
    Next j, i
    End Sub
    В качестве тестового примера введем внутри программы при помощи функции Array список из 10 фамилий. После чего вызовем подпрограмму
    СортировкаСимвольногоМассиваМетодомПузырька на выполнение. В четвертый столбец выводятся фамилии, отсортированные по алфавиту.
    Sub ТестСортировкиСимвольногоМассиваМетодомПузырка()
    Const N = 10
    Dim a As Variant, i As Long
    ' инициализация тестового массива a
    a = Array( "Иванов", "Петров", "Сидоров", "Сидорова", "Ядренцев", _
    "Симонян", "Андреев", "Вяхирев", "Шашилов", "Нестеров")
    Sheets("Лист3").Select
    Call СортировкаСимвольногоМассиваМетодомПузырька(a, N)
    For i = 1 To N
    Cells(i, 4) = a(i)
    Next i
    End Sub
    8.2.2. Метод "пузырька" для структур
    Обычно сортировать необходимо массивы сложных структурных пе- ременных. Для примера возьмем список сотрудников, в котором имеются следующие сведения: фамилия, имя, отчество, возраст и зарплата. Напи-

    96
    сать подпрограмму, которая сортирует этот массив по любому заказанному ключу.
    Введем пользовательский тип данных FullName, состоящий из пяти по- лей разного типа: Fam - фамилия; Name1 - имя; Name2 - отчество; Age - возраст; Zarpl - зарплата сотрудников. В подпрограмме введем еще один формальный параметр Par, задающий номер поля, по которому необходи- мо сортировать список.
    описание пользовательского типа должно находиться вначале
    ‘ модуля
    Type FullName
    Fam As String: Name1 As String: Name2 As String
    Age As Integer: Zarpl As Double
    End Type
    Подпрограмма сортировки по разным параметрам
    Sub СортировкаСтруктурногоМассиваМетодомПузырька(a() _
    As FullName, n As Long, Par As Integer)
    Dim t As FullName, i As Long, j As Long, B As Boolean
    For i = 1 To n - 1
    For j = 1 To n - i
    'Переменная B отвечает на вопрос: нужно ли переставлять
    ’ записи?
    Select Case Par
    Case 1: B = a(j + 1).Fam < a(j).Fam ‘ По фамилии
    Case 2: B = a(j + 1).Name1 < a(j).Name1 ‘ По имени
    Case 3: B = a(j + 1).Name2 < a(j).Name2 ‘ По отчеству
    Case 4: B = a(j + 1).Age < a(j).Age
    По возрасту
    Case 5: B = a(j + 1).Zarpl < a(j).Zarpl ‘ По зарплате
    End Select
    If B Then
    ' Перестановка элементов массива пользовательского типа t = a(j): a(j) = a(j + 1): a(j + 1) = t
    End If
    Next j, i
    End Sub
    Для тестирования подпрограммы введем в первые пять столбцов рабо- чего листа “Лист4” список из 10 элементов структурного типа: в первый столбец – фамилии, во второй – имя, в третий – отчество, в четвертый – возраст и в пятый – величины зарплаты всех сотрудников. После сорти- ровки в шестой, седьмой, восьмой, девятый и десятый столбцы выводится отсортированный массив.
    Sub ТестСортировкиСтруктурногоМассиваМетодомПузырка()
    Const n = 10
    Dim a(10) As FullName, i As Long, Par As Integer
    Sheets("Лист4").Select
    For i = 1 To n ' Считывание списка сотрудников a(i).Fam = Cells(i, 1)

    97
    a(i).Name1 = Cells(i, 2) a(i).Name2 = Cells(i, 3) a(i).Age = Cells(i, 4) a(i).Zarpl = Cells(i, 5)
    Next i
    Par = Val(InputBox("Введите параметр сортировки" + Chr(13) + _
    "1. По фамилии" + Chr(13) + "2. По имени" + Chr(13) + _
    "3. По отчеству" + Chr(13) + "4. По возрасту" + Chr(13) + _
    "5. По зарплате"))
    Call СортировкаСтруктурногоМассиваМетодомПузырька(a, n, Par)
    For i = 1 To n ' Запись отсортированного списка сотрудников
    Cells(i, 6) = a(i).Fam
    Cells(i, 7) = a(i).Name1
    Cells(i, 8) = a(i).Name2
    Cells(i, 9) = a(i).Age
    Cells(i, 10) = a(i).Zarpl
    Next i
    End Sub
    8.3. Сортировка методом выбора
    К существенным недостаткам пузырьковой сортировки следует отне- сти большое количество перестановок. Следующая простая сортировка, уменьшающая количество перестановок – сортировка методом выбора.
    Смысл такой сортировки заключается в следующем.
    Находим положение максимального элемента во всем массиве и пере- ставляем его с первым элементом. В результате первый элемент встал на свое место. Дальше проделываем такие же операции для второго элемента, затем для третьего и так до N-1-го. В этом случае последний элемент авто- матически встает на свое место.
    1. i=1.
    2. j=i+1; jmax=i.
    3. Если A
    j
    > A
    jmax
    , то jmax=j.
    4. j=j+1.
    5. Если j6. Если A
    j
    > A
    jmax
    , то переставить A
    i и A
    jmax
    7. i=i+1.
    8. Если i≤N-1, перейти на 2.
    Нетрудно заметить, что в данном алгоритме тело внутреннего цикла выполняется столько же раз, как и в методе "пузырька".
    На примере числового массива, состоящего из 6 элементов, рассмотрим данный алгоритм сортировки. Затененные элементы не участвуют в сорти- ровке на следующем шаге.

    98 7 1 8 3 6 9 Исходный массив
    9 1 8 3 6 7 1-ый шаг. 1 перестановка (7-9)
    9 8 1 3 6 7 2-ый шаг. 1 перестановка (1-8)
    9 8 7 3 6 1 3-ий шаг. 1 перестановка (1-7)
    9 8 7 6 3 1 4-ый шаг. 1 перестановка (3-6)
    9 8 7 6 3 1 5-ый шаг. Нет перестановок
    Ниже представлена подпрограмма, реализующая этот алгоритм.
    Sub СортировкаМассиваМетодомВыбора(a() As Double, n As Long)
    Dim t As Double, i As Long, j As Long, jmax As Long
    For i = 1 To n - 1 jmax = i
    imax – номер максимального элемента
    For j = i + 1 To n ‘ Поиск положения максимального элемента
    If a(j) > a(jmax) Then jmax = j
    Next j
    If a(jmax) > a(i) Then
    ' Перестановка i-того и максимального элементов
    t = a(jmax): a(jmax) = a(i): a(i) = t
    End If
    Next i
    End Sub
    8.4. Сортировка методом вставки
    В этом методе каждый очередной элемент вставляется в упорядочен- ный к этому времени подмассив так, чтобы не нарушить упорядоченности.
    Рассмотрим алгоритм данной сортировки на том же примере.
    7 1 8 3 6 9 Первый элемент всегда упорядочен
    7 1 8 3 6 9 Второй элемент (1) ставим на свое место в подмассиве из двух элементов
    8 7 1 3 6 9 Третий элемент (8) ставим на свое место
    8 7 3 1 6 9 Четвертый элемент (3) ставим на свое место
    8 7 6 3 1 9 Пятый элемент (6) ставим на свое место
    9 8 7 6 3 1 Шестой элемент (9) ставим на свое место
    Sub СортировкаМассиваМетодомВставки(a() As Double, n As Long)
    Dim t As Double, i As Long, j As Long
    For i = 2 To n t = a(i) ‘ Этот элемент надо поставить в упорядоченный массив
    первых i-1 элементов
    For j = i To 2 Step –1 ‘ Шагаем от i-того до 1-го элемента
    If a(j - 1) > t Then Exit For
    Сдвигаем вправо все элементы, освобождая место под
    ‘ i-тый элемент a(j) = a(j - 1)
    Next j

    99
    a(j) = t ‘Ставим i-тый элемент на свое место так, чтобы
    ‘ i-первых элементов были упорядочены
    Next i
    End Sub
    8.5. Быстрая сортировка
    На практике применяется огромное количество методов сортировки массивов. Рассмотрим теперь более сложную сортировку, получившую на- звание
    быстрая сортировка.
    Ниже будет показано, что на больших мас- сивах она работает значительно быстрее, чем рассмотренные простые сор- тировки.
    Алгоритм быстрой сортировки заключается в следующем. Начинаем сортировать массив от 1-го до n-го элементов. Выбираем средний элемент
    e
    =
    a
    ([(1+n)/2]) и путем минимального количества перестановок добиваемся, чтобы он стоял так, чтобы слева от него все элементы были ≥
    e
    , а справа <
    e
    Затем так же поступаем с левым и правым подмассивами, если длина их
    >1. Затем для каждого из новых подмассивов поступаем так же. И так до тех пор, пока длина всех подмассивов будет =1. Внизу рассмотрены этапы сортировки массива из 10 элементов. Элементы, которые необходимо по- ставить на данном шаге на свое место, затенены. Переменные L и R озна- чают левую и правую границу сортируемых подмассивов. Переменные i и j описаны в программе.

    100 1 2 3 4 5 6 7 8 9
    10 Номера элементов
    74 12 94 39 50 77 55 73 22 60 i=2, j=10,
    L=1,
    R=10 60 12
    Меняем 12 с 60 местами и i=3, j=9 73 39
    Меняем 73 с 39 местами и i=5, j=7 55 50
    Меняем 55 с 50 местами и i=6, j=6 74 60 94 73 55 77 50 39 22 12 i=7, j=6.
    Теперь подмассив слева от 50 содержит элемен- ты которые>50, а справа меньше 50 74 60 94 73 55 77
    L=1, R=6 , i=1, j=3. Сортируем теперь под- массив от 1-го до 6-го элементов. L=1, R=6 94 74
    Меняем 74 с 94 местами и i=2, j=2.
    94 60 74 73 55 77 Сортируем теперь подмассив от 2-го до 6-го элемента. L=2, R=6, i=2,j=6 77 60 i=4, j=4 77 74 73 55 60 L=2,
    R=3,i=2, j=3 77 74
    L=5,
    R=6, i=3, j=2 94 77 74 73 55 60 50 39 22 12 L=5,R=6 94 77 74 73 60 55 50 39 22 12 Окончательно отсортирован- ный массив
    Ниже представлена подпрограмма для сортировки массива по убыва- нию методом быстрой сортировки. Внутри подпрограммы происходит об- ращение к самой себе. Такие программы называются рекурсивными.
    Sub СортировкаМассиваБыстрая(a() As Double, L As Long, R As Long)
    Dim e As Double, t As Double, i As Long, j As Long i = L: j = R: e = a((i + j) \ 2)
    ' Цикл, в котором элемент
    1   ...   7   8   9   10   11   12   13   14   ...   17


    написать администратору сайта