Графік синус ікс. Функції y = sin x, y = cos x, y = mf(x), y = f(kx), y = tg x, y = ctg x

Мабуть, найпростіший алгоритм сортування - це сортування вибором. Судячи з назви сортування, необхідно вибирати щось (максимальний або мінімальний елементи масиву). Алгоритм сортування вибором знаходить у вихідному масиві максимальний або мінімальний елементи, залежно від того, як необхідно сортувати масив, за зростанням або зменшенням. Якщо масив має бути відсортований за зростанням, з вихідного масиву необхідно вибирати мінімальні елементи. Якщо ж масив необхідно відсортувати за зменшенням, то слід вибирати максимальні елементи.

Допустимо необхідно відсортувати масив за зростанням. У вихідному масиві знаходимо мінімальний елемент, міняємо його місцями із першим елементом масиву. Вже з усіх елементів масиву один елемент стоїть на своєму місці. Тепер розглядатимемо не відсортовану частину масиву, тобто всі елементи масиву, крім першого. У невідсортованій частині масиву знову шукаємо мінімальний елемент. Знайдений мінімальний елемент міняємо місцями з другим елементом масиву тощо. Таким чином, суть алгоритму сортування вибором зводиться до багаторазового пошуку мінімального (максимального) елементів у невідсортованій частині масиву. Відсортуємо масив із семи чисел згідно з алгоритмом «Сортування вибором».

вихідний масив: 3 3 7 1 2 5 0
1) Отже, знаходимо мінімальний елемент у масиві. 0 – мінімальний елемент
2) Змінюємо місцями мінімальний та перший елементи масиву.
Поточний масив: 0 3 7 1 2 5 3
3) Знаходимо мінімальний елемент у невідсортованій частині масиву. 1 – мінімальний елемент
4) Змінюємо місцями мінімальний та перший елементи масиву.
Поточний масив: 0 1 7 3 2 5 3
5) min = 2
6) Поточний масив: 0 1 2 3 7 5 3
7) min = 3
8) Поточний масив: 0 1 2 3 7 5 3 в масиві нічого не змінилося, тому що 3 стоїть на своєму місці
9) min = 3
10) Кінцевий вид масиву: 0 1 2 3 3 5 7 – масив відсортований

Запрограмуємо алгоритм сортування вибором С++.

// sorting_choices.cpp: визначає точку входу для консольної програми. #include "stdafx.h" #include #include #include using namespace std; void choicesSort(int*, int); // прототип функції сортування вибором int main (int argc, char * argv) (srand (time (NULL)); setlocale (LC_ALL, "rus"); cout<< "Введите размер массива: "; int size_array; // длинна массива cin >> size_array; int *sorted_array = new int; // одновимірний динамічний масив for (int counter = 0; counter< size_array; counter++) { sorted_array = rand() % 100; // заполняем массив случайными числами cout << setw(2) << sorted_array << " "; // вывод массива на экран } cout << "\n\n"; choicesSort(sorted_array, size_array); // вызов функции сортировки выбором for (int counter = 0; counter < size_array; counter++) { cout << setw(2) << sorted_array << " "; // печать отсортированного массива } cout << "\n"; delete sorted_array; // высвобождаем память system("pause"); return 0; } void choicesSort(int* arrayPtr, int length_array) // сортировка выбором { for (int repeat_counter = 0; repeat_counter < length_array; repeat_counter++) { int temp = arrayPtr; // временная переменная для хранения значения перестановки for (int element_counter = repeat_counter + 1; element_counter < length_array; element_counter++) { if (arrayPtr >arrayPtr) ( temp = arrayPtr; arrayPtr = arrayPtr; arrayPtr = temp; ) ) ) )

Алгоритм сортування вибором ґрунтується на алгоритмі пошуку максимального (мінімального) елемента. Фактично алгоритм пошуку є найважливішою частиною сортування вибором. Оскільки основне завдання сортування - упорядкування елементів масиву, необхідно виконувати перестановки. Обмін значень елементів сортованого масиву відбувається в рядках 4850 . Якщо змінити знак > в рядку 46на знак менше, то сортуватиметься масив за спаданням. Результат роботи програми показано малюнку 1.

Рисунок 1 — Сортування вибором

Урок із серії: «Програмування мовою Паскаль»

Процес обробки та пошуку інформації при вирішенні багатьох завдань проходить швидше та ефективніше, якщо дані розташовані у певному порядку. Наприклад, різні списки студентів, учнів, співробітників — за абеткою, числові дані від більшого значення до меншого (або навпаки) тощо.

Існує досить багато різних методів сортування масивів, що відрізняються один від одного ступенем ефективності, під якою розуміється кількість порівнянь та кількість обмінів, вироблених у процесі сортування. Розглянемо докладно деякі з них.

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

При сортування масивуметодом вибору застосовується базовий алгоритм пошуку максимального (мінімального) елемента та його номера.

Алгоритм сортування масиву методом вибору:

  1. Для вихідного масиву виберіть максимальний елемент.
  2. Поміняти його місцями з останнім елементом (після цього найбільший елемент стоятиме на своєму місці).
  3. Повторити п.п. 1-2 з n-1 елементами, що залишилися, тобто розглянути частину масиву, починаючи з першого елемента до передостаннього, знайти в ньому максимальний елемент і поміняти його місцями з передостаннім (n-1)- м елементом масиву, потім з залишилися (n-2 )-мя елементами і так далі, поки не залишиться один елемент, що вже стоїть на своєму місці.

Для впорядкування масиву знадобиться (n-1) переглядів масиву. У процесі сортування збільшуватиметься відсортована частина масиву, а невідсортована відповідно зменшуватиметься.

При сортуванні даних виконується обмін вмісту змінних. Для обміну необхідно створювати тимчасову змінну, в якій зберігатиметься вміст однієї зі змінних. В іншому випадку її вміст виявиться загубленим.

Завдання 1. Масив із 10 елементів відсортувати за зростанням методом простого перебору.

Напишемо процедуру. Вхідним параметром для неї буде масив. Він буде і вихідним параметром. Тому описуємо його як параметр-змінна (з ключовим словом var).

У процедурі зовнішній цикл по i - визначає довжину частини масиву, що розглядається. Вона змінюватиметься від n до 2.

Внутрішній цикл j використовується для пошуку максимального елемента та його номера. Як початкове значення максимуму розумно взяти значення останнього елемента частини масиву.

Програмний код процедури:

Програмний код основної програми:

program primer_1; const n = 10; type myarray = array of integer; var a:myarray; Procedure sorting1(var a: myarray); (Лінійне сортування (сортування відбором)) ... begin (main) writeln("Введіть вихідний масив:"); для i:=1 до n до read(a[i]); sorting1(a); writeln("Відсортований масив:"); for i:=1 to 10 do write(a[i]," "); writeln; end.

Процес упорядкування елементів у масиві за зростанням методом відбору:

Номер елементу 1 2 3 4 5
Вихідний масив 8 7 5 4 2
Перший перегляд 2 7 5 4 8
Другий перегляд 2 4 5 7 8
Третій перегляд 2 4 5 7 8
Четвертий перегляд 2 4 5 7 8

При впорядкуванні масиву за спаданням необхідно переміщати мінімальний елемент. Навіщо в алгоритмі знаходження максимального елемента достатньо знак «>» поміняти на знак «<«.

Сортування масиву методом простого обміну (методом бульбашки)

Найбільш відомим методом сортування є сортування пухирцевим методом. Його популярність пояснюється назвою, що запам'ятовується, і простим алгоритмом.

Метод заснований на тому, що в процесі виконання алгоритму «легші» елементи масиву поступово «спливають».

Особливістю даного методу є порівняння кожного елемента з усіма, а порівняння в парах сусідніх елементів. Виконується кілька послідовних переглядів масиву від початку до кінця. Якщо сусідні елементи розташовані «неправильно», вони міняються місцями.

Алгоритм сортування масиву за зростанням методом простого обміну:

  1. Почнемо перегляд з першої пари елементів (a та a). Якщо перший елемент цієї пари більший за другий, то міняємо їх місцями, інакше залишаємо без зміни. Потім беремо другу пару елементів (a і a), якщо другий більший за третій, то також змінюємо їх, далі порівнюємо третій і четвертий, і якщо третій більше за четвертий, змінюємо їх місцями, і т.д. Останніми порівнюємо (n-1)-ий та n-ий елементи. При першому обході масиву будуть переглянуті всі пари елементів масиву a[i] та a для i від 1 до (n-1). В результаті максимальний елемент масиву переміститься до кінця масиву.
  2. Оскільки найбільший елемент знаходиться на своєму місці, розглянемо частину масиву без нього, тобто з першого до (n-1) - го елемента. частини масиву, тобто на (n-1) - е місце у всьому масиві.
  3. Ці дії продовжують доти, доки кількість елементів у поточній частині масиву не зменшиться до двох. У цьому випадку необхідно виконати останнє порівняння та впорядкувати останні два елементи.

Неважко помітити, що перетворення масиву, що складається з n елементів, необхідно переглянути його n–1 раз, щоразу зменшуючи діапазон перегляду однією елемент.

Нижче наведено текст процедури сортування масиву за зростанням методом бульбашки.

Для впорядкування елементів масиву щодо зменшення їх значень необхідно при порівнянні елементів масиву знак «>» замінити на «<«.

Процес упорядкування елементів у масиві за зростанням методом обміну:

Номер елементу 1 2 3 4 5
Вихідний масив 8 7 5 4 2
Перший перегляд 7 5 4 2 8
Другий перегляд 5 4 2 7 8
Третій перегляд 4 2 5 7 8
Четвертий перегляд 2 4 5 7 8

У чому ідея сортування вибором?

  1. У невідсортованому підмасиві шукається локальний максимум (мінімум).
  2. Знайдений максимум (мінімум) змінюється місцями з останнім (першим) елементом у підмасиві.
  3. Якщо в масиві залишилися невідсортовані підмасиви, дивись пункт 1.
Невеликий ліричний відступ. Спочатку у своїй серії статей я планував послідовно викладати матеріал про класи сортувань у порядку суворої черги. Після планувалися статті про інші вставні алгоритми: пасьянсная сортування, сортування таблицею Юнга, сортування вивертанням тощо.

Однак, зараз у тренді нелінійність, тому, не написавши ще всі публікації про сортування вставками, сьогодні почну паралельну гілку для сортування вибором. Те саме потім зроблю для інших алгоритмічних класів: сортувань злиттям, сортувань розподілом і т.п. Це загалом дозволить писати публікації то з однієї теми, то з іншої. З таким тематичним чергуванням буде веселіше.

Сортування вибором: Selection sort


Просто і невигадливо - проходимо масивом у пошуках максимального елемента. Знайдений максимум міняємо місцями із останнім елементом. Невідсортована частина масиву зменшилася однією елемент (не включає останній елемент, куди ми переставили знайдений максимум). До цієї невідсортованої частини застосовуємо ті ж дії – знаходимо максимум і ставимо його на останнє місце у невідсортованій частині масиву. І так продовжуємо доти, доки невідсортована частина масиву не зменшиться до одного елемента.

Def selection(data): for i, e in enumerate(data): mn = min(range(i, len(data)), key=data.__getitem__) data[i], data = data, e return data

Сортування простим вибором є грубий подвійний перебір. Чи можна її покращити? Розберемо кілька модифікацій.

Двостороннє сортування вибором: Double selection sort


Схожа ідея використовується в , яка є варіантом бульбашкового сортування. Проходячи по невідсортованій частині масиву, ми, крім максимуму, також попутно знаходимо і мінімум. Мінімум ставимо на перше місце, максимум на останнє. Таким чином, невідсортована частина при кожній ітерації зменшується одразу на два елементи.

На перший погляд здається, що це прискорює алгоритм у 2 рази – після кожного проходу невідсортований підмасив зменшується не з одного, а з двох боків. Але при цьому в 2 рази збільшилася кількість порівнянь, а кількість свопів залишилася незмінною. Подвійний вибір лише трохи збільшує швидкість алгоритму, а деякими мовами навіть чомусь працює повільніше.

Відмінність сортувань вибором від сортувань вставками

Може здатися, що сортування вибором - це суть те саме, загальний клас алгоритмів. Ну, або сортування вставками – різновид сортувань вибором. Або сортування вибором – окремий випадок сортувань вставками. І там, і там ми по черзі з невідсортованої частини масиву витягаємо елементи і перенаправляємо їх у відсортовану область.

Головна відмінність: у сортуванні вставками ми витягуємо з невідсортованої частини масиву будь-якийелемент і вставляємо його на своє місце у відсортованій частині. У сортуванні вибором ми цілеспрямовано шукаємо максимальнийелемент (або мінімальний), яким доповнюємо відсортовану частину масиву. У вставках ми шукаємо куди вставити черговий елемент, а у виборі - ми заздалегідь вже знаємо, в яке місце поставимо, але при цьому потрібно знайти елемент, що відповідає цьому місцю.

Це робить обидва класи алгоритмів зовсім відмінними один від одного за своєю суттю та застосовуваними методами.

Бінго-сортування: Bingo sort

Цікавою особливістю сортування вибором є незалежність швидкості від характеру даних, що сортуються.

Наприклад, якщо масив майже відсортований, то, як відомо, сортування вставками його обробить набагато швидше (навіть швидше ніж швидке сортування). А реверсно впорядкований масив для сортування вставками є виродженою нагодою, вона сортуватиме його максимально довго.

А для сортування вибором часткова або реверсна впорядкованість масиву ролі не відіграє - вона обробить його приблизно з тією ж швидкістю, як і звичайний рандом. Також для класичного сортування вибором неважливо, чи складається масив з унікальних або повторюваних елементів - на швидкість це практично не впливає.

Але в принципі, можна вимудрити і модифікувати алгоритм так, щоб при деяких наборах даних працювало швидше. Наприклад, бінго-сортировка враховує, якщо масив складається з елементів, що повторюються.

Тут фокус у цьому, що у невпорядкованої частини запам'ятовується як максимальний елемент, а й визначається максимум для наступної ітерації. Це дозволяє при повторюваних максимумах не шукати їх знову щоразу, а ставити на своє місце відразу як тільки цей максимум в черговий раз зустріли в масиві.

Алгоритмічна складність залишилася такою самою. Але якщо масив складається з чисел, що повторюються, то бінго-сортировка впорається в десятки разів швидше, ніж звичайне сортування вибором.

# Бінго-сортування def bingo(data): # Перший прохід. max = len(data) - 1 nextValue = data for i in range(max - 1, -1, -1): if data[i] > nextValue: nextValue = data[i] while max and data == nextValue: max -= 1 # Наступні проходи. while max: value = nextValue nextValue = data for i in range(max - 1, -1, -1): if data[i] == value: data[i], data = data, data[i] max -= 1 elif data[i] > nextValue: nextValue = data[i] while max and data == nextValue: max -= 1 return data

Циклічне сортування: Cycle sort

Циклічне сортування цікаве (і цінне з практичної точки зору) тим, що зміни серед елементів масиву відбуваються тоді і тільки тоді, коли елемент ставиться на своє кінцеве місце. Це може стати в нагоді, якщо перезапис у масиві - дуже дороге задоволення і для дбайливого ставлення до фізичної пам'яті потрібно звести до мінімуму кількість змін елементів масиву.

Працює так. Перебираємо масив, назвемо X черговий осередок у цьому зовнішньому циклі. І дивимося на яке місце в масиві потрібно вставити черговий елемент із цього осередку. На тому місці, куди потрібно вставити, знаходиться якийсь інший елемент, його відправляємо в буфер обміну. Для цього елемента в буфері теж шукаємо його місце в масиві (і вставляємо це місце, а в буфер відправляємо елемент, що опинився в цьому місці). І для нового числа в буфері чинимо ті ж дії. Доки має тривати цей процес? Поки що черговий елемент у буфері обміну не виявиться тим елементом, який потрібно вставити саме в осередок X (поточне місце в масиві в головному циклі алгоритму). Рано чи пізно цей момент відбудеться і тоді в зовнішньому циклі можна перейти до наступного осередку і повторити ту саму процедуру.

В інших сортуваннях вибором ми шукаємо максимум/мінімум, щоб поставити їх на останнє/перше місце. У cycle sort так виходить, що мінімум на перше місце в підмасиві перебуває сам, в процесі того, як кілька інших елементів ставляться на свої законні місця десь у середині масиву.

І тут алгоритмічна складність так само залишається в межах O( n 2). На практиці циклічне сортування працює навіть у кілька разів повільніше, ніж звичайне сортування вибором, тому що доводиться більше бігати масивом і частіше порівнювати. Це ціна за мінімально можливу кількість перезаписів.

# Циклічне сортування def cycle(data): # Проходимо по масиву в пошуку циклічних кругообігів for cycleStart in range(0, len(data) - 1): value = data # Шукаємо, куди вставити елемент pos = cycleStart for i in range(cycleStart + 1, len(data)): якщо data[i]< value: pos += 1 # Если элемент уже стоит на месте, то сразу # переходим к следующей итерации цикла if pos == cycleStart: continue # В противном случае, помещаем элемент на своё # место или сразу после всех его дубликатов while value == data: pos += 1 data, value = value, data # Циклический круговорот продолжается до тех пор, # пока на текущей позиции не окажется её элемент while pos != cycleStart: # Ищем, куда переместить элемент pos = cycleStart for i in range(cycleStart + 1, len(data)): if data[i] < value: pos += 1 # Помещаем элемент на своё место # или сразу после его дубликатов while value == data: pos += 1 data, value = value, data return data

Млинці сортування

Алгоритм, який освоїли всі рівні життя – від до .

У найпростішому варіанті ми в невідстортованій частині масиву шукаємо максимальний елемент. Коли максимум знайдено – робимо два різкі розвороти. Спочатку перевертаємо ланцюжок елементів так, щоб максимум опинився на протилежному кінці. Потім перевертаємо весь невідсортований підмасив, у результаті максимум потрапляє на своє місце.

Подібні кордибалети, взагалі кажучи, призводять до алгоритмічної складності O( n 3). Це дресовані інфузорії перекидаються одним махом (тому у їх виконанні складність O( n 2)), а при програмуванні розворот частини масиву – це додатковий цикл.

Млинна сортування дуже цікава з математичної точки зору (кращі уми розмірковували над оцінкою мінімальної кількості переворотів, достатніх для сортування), є більш складні постановки завдання (з так званою підгорілою однією стороною). Тема млинців вкрай цікава, можливо, напишу ґрунтовнішу монографію з цих питань.

# Млинне сортування def pancake(data): if len(data) > 1: for size in range(len(data), 1, -1): # Позиція максимуму в невідсортованій частині maxindex = max(range(size), key = data.__getitem__) if maxindex + 1 != size: # Якщо максимум не слова, то потрібно розгорнути if maxindex != 0: # Перевертаємо так, # щоб максимум виявився зліва data[:maxindex+1] = reversed(data[:maxindex +1]) # Перевертаємо невідсортовану частину масиву, # максимум стає на своє місце data[:size] = reversed(data[:size]) return data

Сортування вибором ефективне настільки, наскільки ефективно організовано пошук мінімального/максимального елемента в невідсортованій частині масиву. У всіх розібраних сьогодні алгоритмах пошук здійснюється як подвійного перебору. А у подвійного перебору, як не крути, алгоритмічна складність буде завжди не кращою за O( n 2). Чи означає це, що всі сортування вибором приречені на середньоквадратичну складність? Зовсім ні, якщо процес пошуку організувати принципово інакше. Наприклад, розглянути набір даних як купу і здійснювати пошук саме в купі. Однак тема купи - це навіть не на статтю, а на цілу сагу, про купи поговоримо обов'язково, але вдруге.



Останні матеріали розділу:

Раннє Нове Час.  Новий час
Раннє Нове Час. Новий час

Розділ ІІІ. РАННІЙ НОВИЙ ЧАС Західна Європа в XVI столітті У XVI столітті в Європі відбулися найбільші зміни. Головна серед них...

Раннє Нове Час — загальна характеристика епохи
Раннє Нове Час — загальна характеристика епохи

ГОЛОВНА РЕДАКЦІЙНА КОЛЕГІЯ: академік О.О. ЧУБАР'ЯН (головний редактор) член-кореспондент РАН В.І. ВАСИЛЬЄВ (заступник головного редактора)...

Економічний розвиток країн Європи у ранній новий час
Економічний розвиток країн Європи у ранній новий час

Пізнє середньовіччя у Європі - це період XVI-першої половини XVII ст. Сьогодні цей період називають раннім новим часом і виділяють у...