Хай маємо множину (масив) з n чисел.
i-та порядкова статистика, це елемент, який буде i-тим за рахунком в масиві, якщо його елементи відсортувати в порядку зростання.
Тоді, наприклад мінімум — це перша порядкова статистика, а максимум — n-та порядкова статистика.
Медіана — елемент, який знаходиться точно посередині між мінімумом і максимумом. Якщо говорити точніше, то якщо n — непарне, то медіана — (n+1)/2-га порядкова статистика, а якщо n — парне, то медіан аж дві: з номером n/2 і n/2+1.
Пошук і-тої порядкової статистики
Найочевидніше, і найпростіше рішення — відсортувати масив, і після цього будь-яку порядкову статистику можна знаходити за одиничний час. Це хороше рішення, якщо нам потрібно шукати багато різних статистик одного масиву. Правда сортування масиву займає час мінімум O(n log(n)).
З усім тим, в багатьох задачах порядкову статистику потрібно знайти лише раз. І це можна зробити за лінійний час. Пошук мінімуму або максимуму — тривіальна задача:
int min(int *a, int l, int r) { int m=l; for(int i=l+1;i<=r;i++) { if(a[i]<a[m]) m=i; } return a[m]; }
Але не сортуючи масив можна знайти й будь-яку іншу порядкову статистику. Секрет в тому, що масив сортується, але не повністю. Розглянемо швидке сортування.
void qsort(int *a, int l, int r) { if(l>=r) return; int c=partition(int *a, int l, int r); qsort(a,l,c); qsort(a,c+1,r); }
Спочатку масив ділять на дві частини, де всі елементи лівої частини менші за будь-який з правої. Ми знаємо, що в лівій частині c елементів. Тому, якщо i — номер елемента якого ми шукаємо, то він знаходиться в лівій частині, якщо інакше він знаходиться в правій частині, але при пошуку в правій частині не забуваємо, що зліва є c менших елементів. Спробуємо написати функцію пошуку порядкової статистики використавши ці міркування:
int nth_element(int *a, int l, int r, int n) { if(l=r) return a[l]; int c=partition(int *a, int l, int r); int k=c-l+1; if(n<=k) return nth_element(a,l,c,n); else return nth_element(a,c+1,r, n-k); }
Функція partition
розглянута тут. Вона працює за час O(r-l). Позначимо розмір частини яка обробляється змінною s. (s=r-l). В ідеалі, при кожному вході в рекурсію s зменшується вдвоє. Тому загальний час роботи O(s+s/2+s/4+s/8+…)=O(2s)=O(s), тобто лінійний. Така оцінка є середньою. Тобто час може бути й гіршим. Існує алгоритм, для якого лінійний час є найгіршим.
Ця стаття не містить . (жовтень 2010) |
Вікіпедія, Українська, Україна, книга, книги, бібліотека, стаття, читати, завантажити, безкоштовно, безкоштовно завантажити, mp3, відео, mp4, 3gp, jpg, jpeg, gif, png, малюнок, музика, пісня, фільм, книга, гра, ігри, мобільний, телефон, android, ios, apple, мобільний телефон, samsung, iphone, xiomi, xiaomi, redmi, honor, oppo, nokia, sonya, mi, ПК, web, Інтернет
Haj mayemo mnozhinu masiv z n chisel i ta poryadkova statistika ce element yakij bude i tim za rahunkom v masivi yaksho jogo elementi vidsortuvati v poryadku zrostannya Todi napriklad minimum ce persha poryadkova statistika a maksimum n ta poryadkova statistika Mediana element yakij znahoditsya tochno poseredini mizh minimumom i maksimumom Yaksho govoriti tochnishe to yaksho n neparne to mediana n 1 2 ga poryadkova statistika a yaksho n parne to median azh dvi z nomerom n 2 i n 2 1 Poshuk i toyi poryadkovoyi statistikiDokladnishe Poshuk poryadkovoyi statistiki Najochevidnishe i najprostishe rishennya vidsortuvati masiv i pislya cogo bud yaku poryadkovu statistiku mozhna znahoditi za odinichnij chas Ce horoshe rishennya yaksho nam potribno shukati bagato riznih statistik odnogo masivu Pravda sortuvannya masivu zajmaye chas minimum O n log n Z usim tim v bagatoh zadachah poryadkovu statistiku potribno znajti lishe raz I ce mozhna zrobiti za linijnij chas Poshuk minimumu abo maksimumu trivialna zadacha int min int a int l int r int m l for int i l 1 i lt r i if a i lt a m m i return a m Ale ne sortuyuchi masiv mozhna znajti j bud yaku inshu poryadkovu statistiku Sekret v tomu sho masiv sortuyetsya ale ne povnistyu Rozglyanemo shvidke sortuvannya void qsort int a int l int r if l gt r return int c partition int a int l int r qsort a l c qsort a c 1 r Spochatku masiv dilyat na dvi chastini de vsi elementi livoyi chastini menshi za bud yakij z pravoyi Mi znayemo sho v livij chastini c elementiv Tomu yaksho i nomer elementa yakogo mi shukayemo to vin znahoditsya v livij chastini yaksho i c displaystyle i leq c inakshe vin znahoditsya v pravij chastini ale pri poshuku v pravij chastini ne zabuvayemo sho zliva ye c menshih elementiv Sprobuyemo napisati funkciyu poshuku poryadkovoyi statistiki vikoristavshi ci mirkuvannya int nth element int a int l int r int n if l r return a l int c partition int a int l int r int k c l 1 if n lt k return nth element a l c n else return nth element a c 1 r n k Funkciya partition rozglyanuta tut Vona pracyuye za chas O r l Poznachimo rozmir chastini yaka obroblyayetsya zminnoyu s s r l V ideali pri kozhnomu vhodi v rekursiyu s zmenshuyetsya vdvoye Tomu zagalnij chas roboti O s s 2 s 4 s 8 O 2s O s tobto linijnij Taka ocinka ye serednoyu Tobto chas mozhe buti j girshim Isnuye algoritm dlya yakogo linijnij chas ye najgirshim Cya stattya ne mistit posilan na dzherela Vi mozhete dopomogti polipshiti cyu stattyu dodavshi posilannya na nadijni avtoritetni dzherela Material bez dzherel mozhe buti piddano sumnivu ta vilucheno zhovten 2010