Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции по МОИ (глава2).doc
Скачиваний:
8
Добавлен:
05.11.2018
Размер:
397.82 Кб
Скачать

Алгоритм 12.2. Нахождение k-го наименьшего элемента со случайным выбором разбивающего элемента

Вход. Массив элементов Array[i], 1in, принадлежащих множеству S, на котором установлен линейный порядок , и целое k, 1kn.

Выход. k-й наименьший элемент из массива Array.

Метод. В основе алгоритма лежит рекурсивная процедура, Selection (Выбор), аналогичная алгоритму 12.1. Отличие заключается в выборе разбивающего элемента m=Array[j]. В данном алгоритме разбивающий элемент выбирается случайным образом внутри последовательности Array[i], 1in. В абсолютном большинстве языков программирования определены датчики равномерно распределённых целых чисел на отрезке от 0 до n–1. Поэтому выбрать случайный элемент в последовательности не составляет труда. В отличие от алгоритма 12.1 в данном случае при каждом отдельном разбиении не гарантируется, что процедура Selection будет применяться к последовательностям, суммарный размер которых меньше исходной последовательности. Однако эффективность данного алгоритма доказывает следующая теорема.

Теорема 10. Среднее время работы алгоритма 12.2 линейно.

Доказательство. Пусть T(n) – среднее время, затрачиваемое алгоритмом Selection на последовательности из n элементов. Предположим для простоты, что все элементы множества S различны. (При наличии повторяющихся элементов результат не изменится).

Пусть элемент m, выбранный в качестве разбивающего, является i-м наименьшим элементом в S. Число i может принимать значения 0, 1, 2,, n–1 равновероятно. Если i>k, то Selection вызывается для последовательности, состоящей из i–1 элементов, а если i<k, то для последовательности, состоящей из n–i элементов. Поэтому среднее время работы рекурсии равно

Остальная часть процедуры Selection занимает время cn для некоторой постоянной c, так что при n2

T(n)  cn +

В качестве упражнения докажите самостоятельно, что если T(1)  c, то T(n)  4cn для всех n2.

Основные элементы программы нахождения k-го наименьшего элемента последовательности с использованием алгоритма 12.2 приведены ниже.

Программа 12.2 Нахождения k-го наименьшего элемента

// Программа использует порядковые статистики для выбора k-го наименьшего элемента

// массива, имеющего длину NUM

#include <stdlib.h>

#include <stdio.h>

#include <io.h>

#include <time.h>

#define NUM 124

Int Selection(int array[], unsigned order, unsigned init, unsigned fin);

Void main()

{

unsigned order, index, counter, logic;

Int result, result1, *array, *array1;

randomize();

//Выделение динамической памяти для массива array

array=new int[NUM];

// В этом месте должна стоять программа ввода массива array,

// из элементов которого необходимо выбрать k-ый по величине (k=order)

for(index=0; index<NUM; array1[index]=array[index]=random(NUM<<1),index++);

// В этом месте необходимо задать элемент order

result=Selection(array, order, 0, NUM-1);

if (result==-32767) printf("Error: order вне границ массива array \n");

else printf("%d-й наименьший элемент массива array %d\n", order, result);

delete [ ] array;

} // Конец main