Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Алгоритмдеу жане багдарламалау негиздери 4 г.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
2.73 Mб
Скачать

19 Дәріс тақырыбы: Медиананы табу.

n элементі үшін медиана деп мәні п элементінің жартысынан кем (немесе тең) және п элементінің келесі жартысынан артық (немесе тең) элементті атайды. Мысалы, 16 12 99 95 18 87 10 элементтері үшін медиана 18-ге тең. Медиананы іздеу міндеті сұрыптау проблемасымен тығыз байланысты, өйткені медиананы анықтаудың айқын әдісі п элементтерін сұрыптау, ал кейін орташа элементті таңдаудан тұрады. Алайда программамен (листинг) орындалатын бөліктеу медиананы едәуір шапшаң іздеуге мүмкіндік береді. Бұл тәсілді п элементінің ортасын іздеу үшін де оңай қорытуға болады. Бұл жағдайда медиананы іздеу - қарапайым жеке жағдай k=n/2- Ұсынылған алгоритм Ч. Хоаром былайша жұмыс жасайды. Алдымен Quicksort-тен c L = 1 және R=п бөліктеу операциясы қолданылады, х бөліктегіш мәні ретінде ак алынады. Нәтижесінде і және j индекстерін аламыз мына шарттарды қанағаттандыратын:

1. аh < х барлығы үшін h < i,

2. ah> х барлығы үшін h >j,

3. i>j

Бұл ретте біз мынадай үш жағдайдың біріне тап келеміз:

1. х бөліктегіш мәні тым аз болды және екі бөліктің арасындағы шекара қажетті к шамадан төмен жатыр. Бөліктеу процесі а1… аr элементтері үшін қайталанады.

Сурет. Шекара тым аз.

2. Таңдап алынған щекараларда өте үлкен болды. Бөліктеу операцияларын аl … ai элементтері үшін қайталаған жөн (сурет).

Сурет. Шекара тым үлкен

3. <k<i: ак элементі жиымды қажетті пропорцияда екі бөлікке бөледі, демек, бұл қажеттінің өзі (сурет).

Сурет. Жоғары шекара

Бөлу процесі үшінші жағдай туындағанға дейін қайталанады. Итерацияның өзі программаның келесідей фрагментімен суреттеледі:

L := 1; R :=n;

WHILE L < R DO BEGIN

х := a[k]; разделение (a[L] ... a[R]);

IF j < k THEN L := i;

IF k < i THEN R := j;

END;

Осы алгоритмнің қисындылығының немқұрайлы дәлелі үшін біз оқырмандарды Хоардың өзінің бірегей жұмысына жібереміз. Енді листингпен берілген бүкіл программа оңай орындалады. Егер әрбір бөлу орташа алғанда қажетті шама бар бөлікті тепе тең бөледі деп шамаласақ, онда қажетті салыстырулардың саны мынаған тең:

п + n/2 + n/4 + ... + 1 = 2n,

яғни ол п ретті. Бұл медианнаны және басқа ұқсас шамаларды тапқан жағдайларда Find программасының “қуаттылығын” және оның тікелей әдістерден артықшылығын да түсіндіреді, онда алдымен кандидаттардың барлық жиыны сұрыпталады, ал кейін k-m элемент таңдап алынады (кей жағдайда бұған п * log(n) операциялар қажет етіледі). Алайда ең қолайсыз жағдайларда бөлудің әрбір қадамы кандидаттар жиынын тек қана бір бірлікке азайтатын болады, нәтижесінде n2 салыстырма қажет болады. Тағы да: егер элементтер саны үлкен емес болса, шамамен 10 десек, алгоритмді қолданудың қажеттілігі бола қоймайтынын еске саламыз Листинг. k-ең үлкен элементін іздеу

PROCEDURE Find(k: INTEGER);

VAR L, R, i, j: index; w, x: item;

BEGIN L := 1, R ;= n;

WHILE L < R DO BEGIN

x := a[k]; i := L; j := R;

REPEAT

WHILE a[i] < x DO i := i+1;

WHILE x < a[j] DO j := j-1;

IF i <= j THEN BEGIN

w := a[i]; a[i] := a[j]; a[j] := w; i := i+1; j := j-1

END

UNTIL i > j;

IF j < k THEN L := i;

IF k < i THEN R := j;

END

END; {Find}