Статьи

Мова Сі в прикладах / Сортування

  1. Метод «бульбашки» [ правити ]
  2. Функція qsort з бібліотеки stdlib [ правити ]
  3. Динамічне виділення пам'яті [ правити ]
  4. Програма впорядкування рядків в алфавітному порядку [ правити ]

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

Метод «бульбашки» [ правити ]

Один з найпростіших алгоритмів рішення - метод «бульбашки».

#include <stdio.h> #define N 1000 int main () {int n, i, j; scanf_s ( "% d", & n); int a [N]; // зчитуємо кількість чисел n // формуємо масив n чисел for (i = 0; i <n; i ++) {scanf_s ( "% d", & a [i]); } For (i = 0; i <n - 1; i ++) {// порівнюємо два сусідні елементи. for (j = 0; j <n - i - 1; j ++) {if (a [j]> a [j + 1]) {// якщо вони йдуть у неправильному порядку, то // міняємо їх місцями. int tmp = a [j]; a [j] = a [j + 1]; a [j + 1] = tmp; }}}}

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

Завдання: Доведіть, що досить n - 1 {\ displaystyle n-1} Завдання: Доведіть, що досить n - 1 {\ displaystyle n-1}   пробігу, щоб елементи масиву впорядкувати пробігу, щоб елементи масиву впорядкувати.

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

Функція qsort з бібліотеки stdlib [ правити ]

Два оператора for, в яких відбувається сортування, можна замінити на один рядок:

qsort (a, n, sizeof (int), cmp);

Це функція, описана в стандартній бібліотеці ANSI C і оголошена в заголовки stdlib.h.

Тому на початку програми потрібно додати

#include <stdlib.h>

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

Четвертий аргумент функції qsort - це ім'я функції, яка вміє порівнювати два елементи масиву. У нашому випадку це

int cmp (const void * a, const void * b) {return * (int *) a - * (int *) b; }

З огляду на зазначеної універсальності функції сортування, функція порівняння отримує в якості аргументу адреси двох блоків, які потрібно порівняти і повертає 1, 0 або -1:

позитивне значення, якщо a> b 0, якщо a == b від'ємне значення, якщо a <b

Оскільки у нас блоки байт - це цілі числа (в 32-бітної архітектури це четирёхбайтовие блоки), то необхідно привести дані покажчики типу (const void *) до типу (int *) і здійснюється це за допомогою дописування перед покажчиком вираження «(const int *) ». Потім потрібно отримати значення змінної типу int, яка лежить за цією адресою. Це робиться за допомогою дописування спереду зірочки.

Таким чином, ми отримали наступну програму

#include <stdio.h> #include <stdlib.h> #define N 1000 int cmp (const void * a, const void * b) {return * (int *) a - * (int *) b; } Int main () {int n, i, j; int a [N]; scanf ( "% d", & n); for (i = 0; i <n; i ++) {// ЧИТАЕМ ВХІД scanf ( "% d", & a [i]); } Qsort (a, n, sizeof (int), cmp); // сортуємо for (i = 0; i <n; i ++) {// ВИВОДИМО РЕЗУЛЬТАТ printf ( "% d", a [i]); } Return 0; }

Динамічне виділення пам'яті [ правити ]

Нижче наведена програма, де пам'ять під масив виділяється динамічно:

#include <stdio.h> #include <stdlib.h> #include <malloc.h> int cmp (const void * a, const void * b) {return * (int *) a - * (int *) b; } Int main () {int n, i; int * a; scanf ( "% d", & n); a = (int *) malloc (sizeof (int) * n); for (i = 0; i <n; i ++) {scanf ( "% d", & a [i]); } Qsort (a, n, sizeof (int), cmp); for (i = 0; i <n; i ++) {printf ( "% d", a [i]); } Free (a); return 0; }

Функція malloc (від англ. Memory allocation --- виділення пам'яті) робить запит до ядра операційної системи по виділенню заданої кількості байт. Єдиний аргумент цієї функції - число байт, яке вам потрібно. Як результат функція повертає покажчик на початок виділеної пам'яті. Покажчик на початок виділеної пам'яті & mbsah - це адреса комірки пам'яті, починаючи з якого йдуть N байт, які ви можете використовувати під будь-які свої потреби. Всю пам'ять, яка була виділена з допомогою функції malloc, потрібно звільняти за допомогою функції free. Аргумент функції free - це покажчик на початок виділеної колись пам'яті.

Програма впорядкування рядків в алфавітному порядку [ правити ]

#include <stdlib.h> #include <string.h> #include <stdio.h> #define N 100 #define M 30 int main (int argc, char * argv []) {char a [N] [M] ; int n, i; scanf ( "% d", & n); for (i = 0; i <n; i ++) scanf ( "% s", & a [i]); qsort (a, n, sizeof (char [M]), (int (*) (const void *, const void *)) strcmp); for (i = 0; i <n; i ++) printf ( "% s \ n", a [i]); return 0; }

Зверніть увагу на складне приведення типів.

Функція strcmp, оголошена в файлі string.h має наступний прототип:

int strcmp (const char *, const char *);

Тобто функція отримує два аргументи - покажчики на шматочки пам'яті, де зберігаються елементи типу char, тобто два масиви символів, які не можуть бути змінені всередині функції strcmp (заборона на зміну задається за допомогою модифікатора const) [1] .

У той же час в якості четвертого елемента функція qsort хотіла б мати функцію типу

int cmp (const void *, const void *);

У мові Сі можна здійснювати приведення типів є типами функції. В даному прикладі тип

int (*) (const char *, const char *); // функція, яка отримує два елементи типу 'const char *' і повертає елемент типу 'int'

приводиться до типу

int (*) (const void *, const void *); // функція, яка отримує два елементи типу 'const void *' і повертає елемент типу 'int'

  1. ^ Функція strcmp відповідно до опису, що видаються командою man 3 strcmp, здійснює порівняння двох рядків і визначає, яка з двох рядків йде першою в алфавітному порядку (порівнює два рядки в лексикографічному порядку), а саме: вона повертає 1, якщо перший рядок "більше "другий (йде після другої в алфавітному порядку), 0 - якщо вони збігаються, і -1 - якщо перший рядок" менше "другий.

Новости

Как создать фото из видео
Кризис заставляет искать дополнительные источники дохода. Одним из таких источников может стать торговля на валютном рынке Форекс. Но чтобы не потерять свои деньги необходимо работать с надежным брокером.

Как оформить группу в вконтакте видео
Дано хотел свой магазин в вк, но не знал с чего начать его делать. Так как хотелось не банальный магазин с кучей ссылок и фото, а красиво оформленный. С меню, с аватаркой. После просмотра видео создал

Как оформить диск малыш от рождения до года из фото и видео
Оформить диск "Малыш от рождения до года" из фото и видео можно совершенно разными способами! Кто-то для достижения данной цели идет на шоу-таланты, кто-то пользуется услугами профессионалов, а кто-то