Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ПСД программы (полн).doc
Скачиваний:
1
Добавлен:
17.04.2019
Размер:
289.79 Кб
Скачать

Алгоритм сортировки методом обмена (методом пузырька)

При просмотре массива упорядочиваются пары соседних элементов: элементы, расположенные не по возрастанию, меняются местами. После просмотра максимальный элемент окажется в конце массива, и второй раз просматриваются уже n - 1 элементов, затем n - 2 и т. д., последний раз просматриваются два элемента.

12 6 14 3 10 // рассматривается n элементов

6 12 14 3 10

6 12 3 14 10

6 12 3 10 14

6 12 3 10 // рассматривается n-1 элементов

6 3 12 10

6 3 10 12

6 3 10 // рассматривается n-2 элементов

3 6 10

3 6 // рассматривается n-3 элементов

/* 2. Сортировка массива x по возрастанию методом обмена */

int k; /* Максимальный индекс просмотра */

. . .

for (k=n-1; k>0; k--)

/* Просмотр элементов x[0], ... , x[k] */

for (i=0; i<k; i++)

/* Сортировка x[i] и x[i+1] */

if (x[i] > x[i+1]) /* Порядок нарушен */

Обмен: x[i] <--> x[i+1];

Реализация алгоритма сортировки методом обмена приведена в программе 7.2.

/* Программа 7.2. Печать входных чисел по возрастанию */

#include <stdio.h>

#define NMAX 100 /* Макс-е количество входных чисел */

void main (void)

{ float x[NMAX]; /* Обрабатываемые числа */

int n; /* Количество чисел */

int i; /* Индекс текущего числа */

int k; /* Максимальный индекс просмотра */

float r; /* Для обмена */

/* 1. Ввод массива x */

printf ("\nВведите количество чисел\n");

scanf ("%d", &n);

printf ("Введите числа\n");

for (i=0; i<n; ++i)

scanf("%f", &x[i]);

/* 2. Сортировка массива x по возрастанию методом обмена */

for (k=n-1; k>0; k--)

for (i=0; i<k; i++)

if (x[i] > x[i+1])

{r=x[i]; x[i]=x[i+1]; x[i+1]=r;}

/* 3. Вывод массива x */

printf("Упорядоченные числа:\n");

for (i=0; i<n; ++i)

printf (" %4.1f", x[i]);

}

Подпрограммы

Задача 15. Вычислить c=n!/(m!*(n-m)!)

Решение А. Использование подпрограммы не обладающей значением.

/* Программа 15а. Вычисление c=n!/(m!*(n-m)!) */ /* с помощью подпрограммы, не обладающей значением */ #include <stdio.h>

void p_fakt (int k, int *f); /* прототип функции */

void main (void)

{ int n, m, c; /* исходные данные и результат */ int f1, f2, f3; /* n!, m!, (n-m)! */

printf("\nВведите два исходных целых числа "); scanf("%d %d", &n, &m);

p_fakt (n, &f1); /* f1 = n! */

p_fakt (m, &f2); /* f2 = m! */

p_fakt (n-m, &f3); /* f3 = (n-m)! */

c = f1 / (f2 * f3); printf ("\n c = %d", c); }

/* Подпрограмма: f = k!; */

void p_fakt (int k, int *f) { int j; /* текущий множитель */

*f=1;

for (j=2; j<=k; j++) *f = *f * j;

return; /* не обязателен */ }

Решение Б. Использование подпрограммы, возвращающей значение (функции).

/* Программа 15б. Вычисление c=n!/(m!*(n-m)!) */ /*с помощью подпрограммы, обладающей значением */ #include <stdio.h>

int fakt (int k); /* прототип функции */

void main(void) { int n, m, c; /* исходные данные и результат */

printf("\nВведите два исходных целых числа "); scanf("%d %d", &n, &m);

c = fakt(n) / (fakt (m) * fakt (n-m));

printf ("\n c = %d", c); }

/* Функция ! */ int fakt (int k)

{ int f; /* k! */

int j; /* текущий множитель */

f=1; for (j=2; j<=k; j++) f = f * j;

return f; /* значение функции */ }

Задача 16. Обмен значений двух переменных

/* Функция обмена значений двух переменных */

#include <stdio.h>

void swap (float *a, float *b)

/* a,b - указатели на заданные переменные */

{ float c;

c = *a; *a =*b; *b = c;

}

/* Гл. функция – драйвер, для тестирования функции swap */

void main()

{ float a=5.5, b=-2.4,

c=10, d=20;

swap (&a, &b);

swap (&c, &d);

printf (“После обмена a=%.1f, b=%.1f”, a, b);

printf (“\n c=%.0f, d=%.0f\n”,c,d);

}

Задача 17. Даны две последовательности вещественных чисел. Найти разность максимальных значений этих последовательностей. Для вычисления максимального значения использовать подпрограмму.

#include <stdio.h>

float fmax ( float m[], int n)

{ float max;

int i;

max=m[0];

for (i=1; i<n; i++)

if (m[i] > max) max=m[i];

return max;

}

int main()

{ float x[25], y[50];

int i, j; i=j=0;

puts(“Vv first posledov”);

while (scanf(“%f”,&x[i++])>0) ;

puts(“Vv second posledov”);

while (scanf(“%f”,&y[j++])>0) ;

printf (“\n Razn = %.2f\n”, fmax(x,i) – fmax(y,j));

return 0;

}

Задача 18. Функция вычисления суммы и количества положительных элементов массива.

void SumPos (float m[ ], int n, float *s, int *k)

/* Вх. параметры:

m – указатель на заданный массив,

n – число элементов массива.

Вых. параметры:

*s – сумма положительных элементов массива,

*k – количество положительных элементов */

{ int i;

for (i=0, *s=0, *k=0; i<n; i++)

if (m[i]>0) { (*s) += m[i]; (*k) ++; }

}

/* Пример вызова функции */

float a[20], s;

int k;

SumPos (a, 20, &s, &k);

Задача 19. Определить, все ли элементы последовательности положительные.

/* Вх. параметры:

p – указатель на заданный массив (последовательность),

n – число элементов.

Значение:

f =1 – все элементы положительные,

f=0 – иначе */

int prov_pol (float p[ ], int n)

{ int i, f;

f=1;

for (i=0; i<n; i++)

if (p[i]<0) f=0;

return f;

}

Задача 20. Составить подпрограмму ввода целого числа, перед которым возможны пробелы, символы "новой строки" и знак

(подобным образом вводится число по формату %d функции scanf).

Тест:

Вход:

412

-5 +234<Ctrl-z><Enter>

void vvod_chisla (int * znach)

{ int sim, znak;

*znach = 0; znak = 1;

/* Пропуск пробелов и "новых строк" до числа */

while ((sim=getchar()) == ' ' || sim=='\n');

/* Чтение знака */

if (sim == '-' || sim == '+')

{ if (sim == '-') znak = -1;

sim = getchar();

}

/* Чтение цифр */

while (sim>='0' && sim<='9')

{ *znach = *znach * 10 + sim - '0';

sim = getchar();

}

*znach = *znach * znak;

}