Проблема с шейкерной сортировкой
Недавно начал учить С. По задаче нужно сортировать стипендию от большего к меньшему шейкерной сортировкой. Написал функцию sortCoc (4 пункт в меню), она не работает. Ниже прикрепляю весь код
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
#define N 30
int u8printf(char *fmt,...){
va_list ap;
va_start(ap,fmt);
int n=mbstowcs(0,fmt,0);
if(n==-1) return -1;
wchar_t wfmt[n+1];
mbstowcs(wfmt,fmt,n+1);
for(int m=128;m<=32768;m*=2){
wchar_t wbuf[m];
int r=vswprintf(wbuf,m,wfmt,ap);
if(r!=-1) {
char buf[m*4];
wcstombs(buf,wbuf,m*4);
fputs(buf,stdout);
return r;
}
}
return -1;
va_end(ap);
}
struct persons {
char name[30];
char secondName[30];
char thirdName[30];
char fac[15];
int age;
int fee;
};
void sortSecondName(struct persons array[], int n);
void sortCoc(struct persons array[], int n);
void vyvids(struct persons array[], int n);
struct persons newElement();
int main() {
setlocale(LC_ALL, "");
struct persons personArray[N] = {
{"Богдан","Корнієнко", "Віталійович", "ІХФ", 17, 1500}, {"Віталій", "Цаль", "Сергієвич", "ТЕФ", 19, 970}, {"Валерія", "Козак", "Олексіївна", "ІПСА", 18, 900}, {"Іван", "Мельник", "Олександрович", "ФІОТ", 19, 2250}, {"Юрій", "Білоус", "Романович", "ТЕФ", 20, 400}
};
int n = 5, ind = 1;
vyvids(personArray, n);
int menuRow;
do {
printf("\n1. Відобразити дані користувачей\n2. Доповнити таблицю користувачей\n3. Сортирувати таблицю за призвіщем\n4. Сортирувати таблицю за степендією\n5. Закінчити программу\n\nОберіть пункт меню: ");
scanf("%d", &menuRow);
switch (menuRow)
{
case 1: vyvids(personArray, n); break;
case 2: n++; personArray[n - 1] = newElement(); break;
case 3: sortSecondName(personArray, n); vyvids(personArray, n); break;
case 4: sortCoc(personArray, n); vyvids(personArray, n); break;
case 5: ind = 0; break;
default:
printf("Невідомий пункт меню\n\n");
break;
}
} while (ind);
return 0;
}
void sortSecondName(struct persons array[], int n) {
int j, i = 0;
struct persons t;
for (i = 0; i < n; i++)
for (j = i; j > 0; j--)
if (strcmp(array[j - 1].secondName, array[j].secondName) > 0) {
t = array[j - 1];
array[j - 1] = array[j];
array[j] = t;
}
}
struct persons newElement() {
struct persons person;
printf("Новий користувач\n");
fgets(person.secondName, sizeof(person.secondName), stdin);
person.secondName[strlen(person.secondName) - 1] = '\0';
printf("Введіть прізвище користувача: ");
fgets(person.secondName, sizeof(person.secondName), stdin);
person.secondName[strlen(person.secondName) - 1] = '\0';
printf("Введіть ім'я користувача: ");
fgets(person.name, sizeof(person.name), stdin);
person.name[strlen(person.name) - 1] = '\0';
printf("Введіть по-батькові користувача: ");
fgets(person.thirdName, sizeof(person.thirdName), stdin);
person.thirdName[strlen(person.thirdName) - 1] = '\0';
printf("Введіть факультет користувача: ");
fgets(person.fac, sizeof(person.fac), stdin);
person.fac[strlen(person.fac) - 1] = '\0';
printf("Введіть вік користувача: ");
scanf("%d", &person.age);
printf("Введіть степендію користувача: ");
scanf("%d", &person.fee);
return person;
}
void swap99(a, b) {
int temp = a;
a = b;
b = temp;
}
void sortFee(struct persons array[], int n) {
struct persons person;
int i, j;
for (i = 0; i < n - 1; i++)
for (j = 0; j < (n - 1) - i; j++)
if (array[j].fee < array[j + 1].fee) {
person = array[j];
array[j] = array[j + 1];
array[j + 1] = person;
}
}
void sortCoc(struct persons array[], int n) {
struct persons person;
int top, bottom, last_swap;
top = 0;
bottom = n;
while (top < bottom) {
last_swap = 0;
for (int i = top; top < bottom; i++) {
if (array[i].fee > array[i+1].fee) {
swap99(array[i].fee, array[i+1].fee);
last_swap = i;
}
}
bottom = last_swap;
for (int j = bottom; bottom < top; j--) {
if (array[j].fee > array[j-1].fee) {
swap99(array[j].fee, array[j-1].fee);
last_swap = j;
}
}
}
}
void vyvids(struct persons array[], int n) {
int i;
printf("--------------------------------------------------------------------------------------------- -\n");
printf("| Дані користувачів |\n");
printf("|--------------------------------------------------------------------------------------------|\n");
printf("| Прізвище| Ім'я| По-батькові| Факультет| Вік| Степ.|\n");
printf("|--------------------|---------------------|---------------------|-----------|------|--------|\n");
for (i = 0; i < n; i++) {
u8printf("|%20s|%21s|%21s|%11s|%6d|%8d|\n", array[i].secondName,
array[i].name, array[i].thirdName, array[i].fac, array[i].age, array[i].fee);
}
printf("----------------------------------------------------------------------------------------------\n\n\n");
}
Ответы (1 шт):
Автор решения: AlexGlebe
→ Ссылка
Куча ошибок. Сначала функция swap - пытаетесь обменять локальные переменные. А надо менять по указателю. Сортировка с обратым ходом у вас недописана, всё скопировано необдуманно и бессмысленно. В вашем примере не добавлены необходимые библиотеки. Вот все переделки :
// библиотеки нужны
# include <stdarg.h>
# include <wchar.h>
// меняем значения по указателю
void swap99(int * a,int * b) {
int temp = *a;
*a = *b;
*b = temp;
}
void sortCoc(struct persons array[], int n) {
int top, bottom, last_swap;
top = 0;
bottom = n;
while (top < bottom) {
last_swap = 0;
// сравнивать нужно индекс i , а не bottom
// цикл на один элемент меньше, потому,
// что обращаетесь к array[i+1].fee
for (int i = top; i < bottom-1; i++) {
if (array[i].fee > array[i+1].fee) {
// меняем значения по указателю
swap99(&(array[i].fee), &(array[i+1].fee));
// индекс bottom должен быть больше последнего на один
last_swap = i+1;
}
}
bottom = last_swap;
// сравнивать нужно индекс j , а не bottom
// не меньше, а больше
for (int j = bottom-1; j > top; j--) {
// чтобы j элемент был больше чем j-1
// нужно сравнивать не [j]>[j-1] а [j]<[j-1]
if (array[j].fee < array[j-1].fee) {
swap99(&(array[j].fee), &(array[j-1].fee));
last_swap = j;
}
}
// забыли индекс top поменять
top = last_swap ;
}
}