
Практическая работа №9
АЛГОРИТМЫ ПОИСКА В ОДНОМЕРНЫХ МАССИВАХ
Цель занятия:
1 Научить производить поиск числа в отсортированном одномерном массиве.
2 Научиться производить поиск числа в неотсортированном одномерном массиве.
Краткие сведения из теории
Методы поиска удобнее рассматривать на примере вектора-строки.
Метод половинного деления
Данный метод применим только для поиска в упорядоченном массиве, причём массив может быть отсортирован как по убыванию, так и по возрастанию. Для поиска числа требуется знать: количество элементов массива, сами элементы массива и искомое число. В исходном массиве, отсортированном в порядке возрастания элементов, находится индекс элемента, стоящего в средине рассматриваемого подмассива и этот элемент сравнивается с искомым числом. (При первой итерации в качестве подмассива выступает весь массив целиком.) Найденный элемент может быть:
– равен искомому числу. В данном случае поиск заканчивается.
– меньше искомого числа. В данном случае поиск продолжается в той части подмассива, которая находится правее найденного элемента.
– больше искомого числа. В данном случае поиск продолжается в той части подмассива, которая находится левее найденного элемента.
В оставшемся подмассиве опять находится номер элемента, стоящего в средине, и найденный элемент сравнивается с искомым числом. Процесс повторяется до тех пор, пока:
– не будет найден элемент массива, равный искомому числу.
– количество элементов подмассива, среди которых осуществляется поиск, не станет равным нулю.
Алгоритм, реализующий данный метод, приведен на рис. 9.1.
На вход алгоритма подаются входные данные (символ 2):
N – количество элементов массива;
A[1..N] – элементы исходного массива;
K – искомое число.
Устанавливаются границы интервала для поиска с помощью переменных: L – левая граница; R – правая граница (символ 3).
Выполняется сравнение значений индексов левой и правой границ (символ 4). Если индекс левого граничного элемента больше индекса правого граничного элемента, то искомое число не входит в массив, и поиск заканчивается с выдачей соответствующего сообщения (символ 5). В противном случае находится индекс I элемента, стоящего в средине рассматриваемого подмассива (символ 6). Для этого выполняется операция целочисленного деления на число 2суммы значений индексов левой и правой границ.
Сравнивается элемент массива, имеющий индекс I и искомое число (символ 7). При этом возможно три альтернативы:
– искомое число равно найденному элементу массива. Выводится сообщение об успешном окончании поиска (символ 8) и алгоритм заканчивает свою работу (символ 11).
– искомое число меньше найденного элемента массива. Правая граница поиска передвигается на элемент массива, стоящий левее элемента с индексом I (символ 9).
– искомое число больше найденного элемента массива. Левая граница поиска передвигается на элемент массива, стоящий правее элемента с индексом I (символ 10).
После этого управление передаётся к символу 4.
Таблица трассировки алгоритма, реализующего метод половинного деления в массиве из 16-и элементов, представлена в таблице 9.1.
Трассировка алгоритма бинарного поиска Таблица 9.1
Исходный массив |
|||||||||||||||
47 |
106 |
147 |
177 |
211 |
224 |
327 |
384 |
430 |
469 |
476 |
575 |
584 |
741 |
858 |
973 |
Индексы элементов массива |
|||||||||||||||
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
L |
R |
R < L |
I |
K ? M[I] |
|||||||||||
Поиск числа, входящего в массив (K = 327) |
|||||||||||||||
1 |
16 |
Нет |
8 |
327<384 |
|||||||||||
1 |
8-1=7 |
Нет |
4 |
327>177 |
|||||||||||
4+1=5 |
7 |
Нет |
6 |
327>224 |
|||||||||||
6+1=7 |
7 |
Нет |
7 |
327=327 |
|||||||||||
Поиск закончен успешно – искомое число найдено. |
|||||||||||||||
Поиск числа, не входящего в массив (K = 76) |
|||||||||||||||
1 |
16 |
Нет |
8 |
76<384 |
|||||||||||
1 |
8-1=7 |
Нет |
4 |
76<177 |
|||||||||||
1 |
4-1=3 |
Нет |
2 |
76<106 |
|||||||||||
1 |
1 |
Нет |
1 |
76>47 |
|||||||||||
2 |
1 |
Да |
|
|
|||||||||||
Поиск неудачен, так как значение индекса левой границы больше значения индекса правой границы. |
Рисунок 9.1 Алгоритм,
реализующий метод половинного деления
Метод последовательного перебора
Данный метод применим для поиска, как в упорядоченном массиве, так и в неупорядоченном. Он заключается в том, что после элемента массива c максимальным индексом (N), дописывается искомое число с индексом N + 1. Затем происходит последовательное сравнение с искомым числом всех элементов массива, начиная с первого. Если элемент массива и искомое число равны между собой, и при этом индекс найденного элемента будет меньше количества элементов массива + 1, то искомое число найдено. Если же индекс найденного элемента будет равен количеству элементов массива + 1, то искомое число отсутствует в массиве.
Алгоритм, реализующий данный метод, приведен на рис. 9.2.
На вход алгоритма подаются входные данные (символ 2):
N – количество элементов массива;
A[1..N] – исходный массив;
K – искомое число.
Вспомогательной переменной присваивается индекс первого элемента массива (I) а дополнительному элементу массива присваивается значение искомого числа (символ 3).
Сравниваются искомое число и текущий элемент массива (символ 4).
Если они не равны между собой, то переходим к следующему элементу (символ 5), иначе сравниваются между собой индекс найденного элемента и количество элементов в массиве (символ 6). Если индекс найденного элемента больше количества элементов в массиве, то выводится сообщение “Число K не найдено” (символ 8), в противном случае искомое число найдено в массиве, и выводится сообщение “Число K найдено” (символ 7) После этого алгоритм заканчивает свою работу (символ 9).
Таблица трассировки алгоритма – в таблице 9.2.
Контрольные вопросы
1 Какие надо внести изменения в алгоритм метода половинного деления, в случае, если исходный массив отсортирован по убыванию?
2 Какие надо внести изменения в алгоритм быстрого последовательного перебора, в случае, если индекс первого элемента равен нулю?
3 Какой алгоритм поиска оптимально определить для нахождения числа в отсортированном массиве и почему?
4 Позволяет ли алгоритм быстрого последовательного перебора производить поиск в массиве, элементами которого являются буквы русского алфавита?
Рисунок
9.2 Алгоритм,
реализующий метод быстрого последовательного
перебора
Трассировка алгоритма, реализующего метод быстрого последовательного перебора. Таблица 9.2
Исходный массив |
|||||||||||||||
569 |
85 |
495 |
556 |
844 |
376 |
791 |
559 |
676 |
641 |
736 |
729 |
810 |
607 |
718 |
430 |
Индексы элементов массива |
|||||||||||||||
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
Поиск числа, входящего в массив (K = 729) |
|||||||||||||||
I |
K = M[I] |
I <= N |
|||||||||||||
1 |
Нет |
Да |
|||||||||||||
2 |
Нет |
Да |
|||||||||||||
3 |
Нет |
Да |
|||||||||||||
4 |
Нет |
Да |
|||||||||||||
5 |
Нет |
Да |
|||||||||||||
6 |
Нет |
Да |
|||||||||||||
7 |
Нет |
Да |
|||||||||||||
8 |
Нет |
Да |
|||||||||||||
9 |
Нет |
Да |
|||||||||||||
10 |
Нет |
Да |
|||||||||||||
11 |
Нет |
Да |
|||||||||||||
12 |
Да |
Да |
|||||||||||||
Поиск закончен успешно – искомое число найдено. |
|||||||||||||||
К=574 |
|||||||||||||||
1 |
Нет |
Да |
|||||||||||||
2 |
Нет |
Да |
|||||||||||||
3 |
Нет |
Да |
|||||||||||||
4 |
Нет |
Да |
|||||||||||||
5 |
Нет |
Да |
|||||||||||||
6 |
Нет |
Да |
|||||||||||||
7 |
Нет |
Да |
|||||||||||||
8 |
Нет |
Да |
|||||||||||||
9 |
Нет |
Да |
|||||||||||||
10 |
Нет |
Да |
|||||||||||||
11 |
Нет |
Да |
|||||||||||||
12 |
Нет |
Да |
|||||||||||||
13 |
Нет |
Да |
|||||||||||||
14 |
Нет |
Да |
|||||||||||||
15 |
Нет |
Да |
|||||||||||||
16 |
Нет |
Да |
|||||||||||||
17 |
Да |
Нет |
|||||||||||||
Поиск неудачен, так как значение индекса найденного элемента массива больше количества элементов в массиве. |