Выбор в линейных списках

Задача выбора. Задан линейный список целых, различных по значению чисел B=, требуется найти элемент, имеющий i-тое наибольшее значение в порядке убывания элементов. При i=1 задача эквивалентна поиску максимального элемента, при i=2 поиску элемента с вторым наибольшим значением.

Поставленная задача может быть получена из задачи поиска j-того минимального значения заменой i=n-j+1 и поиском i-того максимального значения. Особый интерес представляет задача выбора при i=a/n, 0

Все варианты задачи выбора легко решаются, если список B полностью отсортирован, тогда просто нужно выбрать i-тый элемент. Однако в результате полной сортировки списка B получается больше информации, чем требуется для решения поставленной задачи.

Количество действий можно уменьшить применяя сортировку выбором только частично до i-того элемента. Это можно сделать, напри мер при помощи функции findi

/* выбор путем частичной сортировки */

int findi(int *s, int n, int i)

{

int c,j,k;

for (k=0; k

Эта функция ищет элемент с индексом i, частично сортируя массив s, и выполняет при этом (n*i) сравнений. Отсюда следует, что функция findi приемлима для решения задачи при малом значении i, и малоэффективна при нахождении медианы.

Для решения задачи выбора i-того наибольшего значения в списке B модифицируем алгоритм быстрой сортировки. Список B разбиваем элементом K1 на подсписки B’ и B, такие, что если Ki -B’, то KiK1, и если Ki — B, то Kii наибольшее значение ищется в списке B’; при jАлгоритм выбора на базе быстрой сортировки в общем эффективен, но для улучшения алгоритма необходимо, чтобы разбиение списка на подсписки осуществлялось почти пополам. Следующий алгоритм эффективно решает задачу выбора i-того наибольшего элемента в списке B, деля его на подсписки примерно равной величины.

1. Если N

2. Если N21 разделим список на P=N/7 подсписков по 7 элементов в каждом, кроме последнего в котором mod(N,7) элементов.

3. Определим список W из медиан полученных подсписков (четвертых наибольших значений) и найдем в W его медиану M (рекурсивно при помощи данного алгоритма) т.е. (P/2+1)-й наибольший элемент.

4. С помощью элемента M разобьем список B на два подсписка B’ с j элементами большими или равными M, и B c N-j элементами меньшими M. При ji повторим процедуру поиска сначала, но только в подсписке B’. При j=i искомый элемент найден, равен M и поиск прекращается. При j i будем искать (i-j)-тый наибольший элемент в списке B.

/* алгоритм выбора делением списка почти пополам */

int search (int *b, int n, int i)

{

int findi(int *, int, int);

int t, m, j, p, s, *w;

if (n

if (ji)

{

for (p=0, t=0; p n; t++)

if (b[t]=m)

{ b[p]=b[t]; p++; }

m=search(b, j, i); /* поиск в B */

}

if (j i)

{

for (p=0, t=0; t n; t++)

if (b[t] m) b[p++]=b[t];

m=search(b, n-j, i-j); /* поиск в B */

}

return m;

}

Рекурсивная функция search реализует алгоритм выбора i-того наибольшего значения. Для ее вызова можно использовать следующую программу

#include

#include

main()

{

int search (int *b, int n, int i);

int *b;

int l, i, k, t;

scanf(%d%d,l,i);

printf

(nВыбор %d максимального элемента из %d штук,i,l);

b=(int *)(calloc(100,sizeof(int)));

for (k=0; k

Используя метод математической индукции, можно доказать, что для функции search требуется выполнить в самом неблагоприятном случае 28*N сравнений.

Действительно, если N

Лекція

Технологія створення програм

Информатика. Алгоритмы поиска и сортировки: Линейный поиск. Центр онлайн-обучения «Фоксфорд»

Похожие статьи:

Понравилась статья? Поделиться с друзьями:
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!:

Adblock
detector