Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Turbo Pascal / Stud_1_1 / LecRus / MainPart.doc
Скачиваний:
118
Добавлен:
03.03.2016
Размер:
5.03 Mб
Скачать

Группировка массива методом прямого обмена

Рассматриваемый метод группировки называют также методом "пузырька".

Запишем сверху вниз элементы :

Просмотр 1 Просмотр 2 Просмотр 3 . . . Просмотр n-1

…… …….. ……

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

Во втором просмотре анализируются пары элементов и , и , ... , и . Вследствие этого самый тяжелый из оставшихся элементов опустится на новое дно, т.е. займет место элемента .

В третьем просмотре анализируются пары элементов и, и , ... , и и т.д.

Работа алгоритма заканчивается, если при очередном просмотре будет определено, что ни разу не имело места нарушение упорядоченности элементов массива, т.е. ни разу не было выполнено условие .

Program Bubble;

Const Nmax = 500;

Type Ar = array[1..Nmax] of real;

Var i,n,m : word;

R : real;

Cond : boolean;

X : Ar;

Begin

Ввод и печать n,X

Cond:=true; m:=n;

While Cond do

Begin

Cond:=false;

For i:=1 to m-1 do

If x[i]>x[i+1] then

Begin

R:=x[i]; x[i]:=x[i+1]; x[i+1]:=r;

Cond:=true;

End;

Dec(m);

End;

Печать Х

End.

Комментарии к программе.

1. Так как количество просмотров заранее неизвестно, то для их перебора используется цикл While, работающий под управлением булевской переменной Cond. После входа в цикл этой переменной присваивается значение false в предположении, что массив уже сгруппирован. После этого в цикле For проверяется справедливость этого предположения. Если обнаружено нарушение упорядоченности, то производится обмен смежных элементов, а переменной Cond присваивается значение true, что влечет за собой повторение работы цикла While, т.е. выполнение очередного просмотра.

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

Сравним работу рассмотренных алгоритмов группировки.

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

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

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

Метод

пузырька

Метод

прямой выборки

Школьный

алгоритм

1,0

1,4

1,6

Следовательно, в общем случае целесообразно применять метод пузырька.

Было произведено также более детальное сравнение методов группировки. Здесь программа создавала одномерный массив, состоящий из 1000 элементов. Каждый элемент – это запись, состоящая из ключа (целое число типа word), строки длиной 50 символов и вещественного числа. Содержимое каждой записи формировалось с помощью генератора случайных чисел. Группирование элементов массива производилось по значению ключа. Чтобы время группировки массива было более-менее заметным, процесс обработки повторялся 1000 раз. Результаты обработки представлены ниже в сравнительной таблице. При этом время обработки, указанное в таблице, – это секунды, затраченные на 1000-кратное повторение соответствующего метода группировки.

Метод

Исходный

массив

Массив по

возрастанию

Массив по

убыванию

Школьный

алгоритм

18,73

16,87

17,41

Молернизир. школьный

алгоритм

8,71

8,51

9,34

Метод прямой

выборки

5,44

5,43

5,77

Метод прямого обмена

3,9

0,73

9,06

Быстрая

сортировка

1,88

2,03

3,17

Примечание. Рассмотренные методы относят к методам сортировки первого порядка. Существуют также несколько методов второго порядка, работающие значительно быстрее, но реализованные по более сложным алгоритмам. Одним из наиболее эффективных является метод быстрой сортировки [12], программная реализация которого приведена в учебном пособии после рассмотрения динамических переменных.

П О И С К В У П О Р Я Д О Ч Е Н Н О М М А С С И В Е

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

Такая задача поиска часто возникает в системах АСУ, САПР и других при выборке информации из различных архивов. Самым простым методом для ее решения является метод прямого перебора, или, как его еще называют, метод линейного поиска. При использовании указанного метода последовательно просматриваются элементы массива до тех пор, пока не будет найден искомый элемент или не станет ясно, после просмотра всего массива, что такого элемента здесь нет.

Program DirectSearch;

Const Nmax = 500;

Type Ar = array[1..Nmax] of word;

Var i,k,n,b : word;

X : Ar;

Begin

Ввод и печать n,X,b

k:=0;

For i:=1 to n do

If x[i]=b then

Begin

k:=i; Break

End;

Печать k

End.

Если , то в массиве анализируется лишь один элемент; если или в массиве отсутствует элемент, равный значению , то анализируются элементов. Среднее количество просмотров элементов массива равно .

Если массив неупорядочен, то метод прямого перебора является единственно возможным. Для упорядоченного массива наиболее эффективным является метод двоичного (бинарного) поиска.

Пусть массив имеет элементов. Сущность алгоритма двоичного поиска сводится к следующему.

1) Рассматривается диапазон поиска . Левая граница диапазона , правая граница . Выходной переменной присваивается нулевое начальное значение.

2) Если , поиск прекращается.

3) Определяется , т.е. индекс середины диапазона.

4) Если , поиск закончен, переменной присваивается значение m . В противном случае - переход к шагу 5.

5) Если , то это означает, что в правой половине подмассива (от m+1 до ) не может быть элемента, равного b. Тогда граница перемещается в точку m-1: . При этом диапазон поиска уменьшается вдвое. Дальше - переход к шагу 2.

6) Если , то аналогичным образом к точке m+1 сдвигается левая граница : . В этом случае диапазон поиска также уменьшается вдвое и производится переход к шагу 2.

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

Примечание. Выполнять в пп.5 и 6 переход в точку m нет смысла, так как элемент уже был проверен.

Program BinarySearch;

Const Nmax = 500;

Type Ar = array[1..Nmax] of integer;

Var i1,i2,k,n,m,b : integer;

X : Ar;

Begin

Ввод и печать n,X,b

i1:=1; i2:=n; k:=0;

While i1<=i2 do

Begin

m:=(k1+k2) div 2;

If x[m]=b then

Begin

k:=m; Break

End;

If x[m]>b then

i2:=m-1

Else

i1:=m+1;

End;

Печать k

End.

Cреднее количество просмотров элементов массива в методе двоичного поиска равно , что значительно меньше значения .

М Н О Г О М Е Р Н Ы Е М А С С И В Ы

В описании типа массива

array [T1] of T

тип Т, определяющий компоненты массива, может быть любым (кроме файла). Следовательно, тип T может быть в частном случае составным типом, в том числе массивом.

Пример.

Const M = 10; N = 15; K = 1; L = 12;

Type T1 = M..N; T2 = K..L; T = real;

Var A : array[T1] of array[T2] of T;

B : array[M..N] of array[K..L] of T .

Компонент такого массива обозначается a[i][j], b[i][j].

Обычно используют сокращенную форму описания массива:

Var A : array[T1,T2] of T;

B : array[M..N,K..L] of T.

В этом случае компонент имеет вид a[i,j], b[i,j].

В нашем примере А и B - это двумерные массивы, т.е. матрицы, элементы которых имеют тип T (в данном случае тип real).

Массивы могут быть и более чем двумерные. Пример трехмерного массива:

Соседние файлы в папке LecRus