Было трудно распутать это, потому что ему, к сожалению, не хватает качеств MCVE ( Минимальный, полный, проверяемый пример ).Использование глобальной переменной для сортировки массива - плохая идея;передать массив в функцию сортировки.
Вы говорите:
... это не сработает, если я попытаюсь отсортировать много массивов
Вы должныобъясните, как это не работает.Одна очевидная проблема заключается в том, что вам нужно скопировать данные в глобальный массив для каждого набора данных, которые будут отсортированы.Это одна из многих причин, почему вы должны передавать массив в функцию сортировки, а не полагаться на глобальные переменные.Обращайтесь с глобальными переменными с осторожностью.Используйте их только тогда, когда альтернатива (передавая в качестве аргументов) слишком мучительна (а «мучительная» - это боль минимального уровня, которая должна заставить вас использовать глобальные переменные, не отталкивайтесь простым «дискомфортом» или даже просто «агонией»).).
Общая информация: у "Элементов" есть буква m - у вашего огромного длинного NUM_OF_ELENENTS_IN_ARRAY нет буквы M в нужном месте.Однако имена переменных и констант слишком длинные для моего удобства.Да;хорошо выбирать значимые имена.Нет;нет необходимости писать грамматически правильное эссе в название.Я использовал NUM_VALUES
;NUM_COLUMNS
тоже подойдет.Они достаточно длинные и значимые.
Если серьезно, у вас есть глобальная переменная OutputBuffer
, для которой нет объяснения - на нее ссылается copyTripleToArray()
, что является нечетным именем для функции, которая копирует6 элементов.Однако более тщательное изучение показывает, что оно используется только при buffer == 1
, но вы никогда не вызываете функцию с buffer == 1
, так что блок кода можно удалить (закомментировать).
Ваша copyTripleToArray()
функцияскромно странно.Вы должны просто предоставить указатель на строку, которую нужно скопировать, и строку, на которую нужно скопировать, и позволить этому начать копирование.Странно, что вам нужно так много параметров.Два или три должно быть достаточно (в зависимости от того, передаете ли вы NUM_VALUES
в функцию или нет).
Слегка пересмотренная версия кода из вопроса
Однако, когда все сказано и сделано,похоже, что код работает.По крайней мере, изменения, которые я сделал в приведенном ниже коде, должны быть тривиальными.Я создал и заполнил массив, и запустил код на нем, и он, кажется, дает правильный результат.
#include <stdio.h>
#include <stdlib.h>
enum { NUM_VALUES = 6 };
enum { NUM_OF_ELEMENTS_IN_ARRAY = NUM_VALUES };
static int sortedArray[][NUM_VALUES]; // Forward declaration
static void copyTripleToArray(int PrimitivePythagoreanTriple[], int index, int buffer, int tempArray[])
{
//if (buffer == 1)
//{
//for (int i = 0; i < NUM_OF_ELEMENTS_IN_ARRAY; i++)
//outputBuffer[index][i] = PrimitivePythagoreanTriple[i];
//}
//else if (buffer == 0)
if (buffer == 0)
{
for (int i = 0; i < NUM_OF_ELEMENTS_IN_ARRAY; i++)
sortedArray[index][i] = PrimitivePythagoreanTriple[i];
}
else
{
for (int i = 0; i < NUM_OF_ELEMENTS_IN_ARRAY; i++)
tempArray[i] = PrimitivePythagoreanTriple[i];
}
}
static void bubbleSort(int arraySize)
{
int tempEntry[NUM_VALUES];
for (int i = 0; i < arraySize - 1; i++)
{
for (int j = 0; j < arraySize - 1 - i; j++)
{
if (sortedArray[j][3] > sortedArray[j + 1][3])
{
copyTripleToArray(sortedArray[j], 0, 2, tempEntry);
copyTripleToArray(sortedArray[j + 1], j, 0, NULL);
copyTripleToArray(tempEntry, j + 1, 0, NULL);
}
if (sortedArray[j][3] == sortedArray[j + 1][3] &&
sortedArray[j][4] > sortedArray[j + 1][4])
{
copyTripleToArray(sortedArray[j], 0, 2, tempEntry);
copyTripleToArray(sortedArray[j + 1], j, 0, NULL);
copyTripleToArray(tempEntry, j + 1, 0, NULL);
}
}
}
}
static void print_array(const char *tag, size_t size, int data[size][NUM_VALUES])
{
printf("%s (%zux%d):\n", tag, size, NUM_VALUES);
for (size_t i = 0; i < size; i++)
{
printf("%3zu:", i);
for (int j = 0; j < NUM_VALUES; j++)
printf(" %3d", data[i][j]);
putchar('\n');
}
}
static int sortedArray[][NUM_VALUES] =
{
// random -n 30 -T '%d %d %d %d %d %d' 10 29 |
// commalist -n 6 -B 4 -b '{ ' -w -W 3 -T ' },'
{ 25, 18, 29, 25, 12, 18, },
{ 29, 29, 24, 23, 26, 28, },
{ 16, 22, 10, 15, 23, 29, },
{ 27, 22, 16, 27, 19, 24, },
{ 17, 18, 10, 20, 15, 24, },
{ 21, 11, 19, 15, 13, 15, },
{ 16, 11, 19, 13, 10, 25, },
{ 17, 17, 15, 27, 26, 24, },
{ 12, 23, 24, 28, 24, 15, },
{ 11, 21, 25, 15, 18, 25, },
{ 12, 14, 25, 11, 13, 29, },
{ 16, 12, 11, 21, 19, 28, },
{ 18, 16, 20, 17, 15, 11, },
{ 13, 18, 11, 23, 23, 18, },
{ 29, 16, 29, 10, 22, 28, },
{ 13, 15, 24, 24, 28, 26, },
{ 28, 26, 13, 27, 18, 27, },
{ 10, 29, 18, 15, 24, 29, },
{ 24, 24, 27, 24, 21, 12, },
{ 10, 28, 12, 11, 27, 25, },
{ 12, 21, 28, 27, 11, 14, },
{ 19, 17, 11, 18, 25, 23, },
{ 19, 21, 10, 21, 20, 22, },
{ 18, 29, 12, 15, 28, 22, },
{ 25, 16, 15, 23, 27, 21, },
{ 28, 16, 11, 10, 24, 23, },
{ 29, 19, 22, 20, 28, 27, },
{ 16, 21, 17, 16, 25, 15, },
{ 11, 23, 17, 19, 27, 13, },
{ 12, 15, 18, 16, 26, 14, },
};
enum { NUM_ROWS = sizeof(sortedArray) / sizeof(sortedArray[0]) };
int main(void)
{
print_array("Before", NUM_ROWS, sortedArray);
bubbleSort(NUM_ROWS);
print_array("After", NUM_ROWS, sortedArray);
return 0;
}
Пример запуска:
Before (30x6):
0: 25 18 29 25 12 18
1: 29 29 24 23 26 28
2: 16 22 10 15 23 29
3: 27 22 16 27 19 24
4: 17 18 10 20 15 24
5: 21 11 19 15 13 15
6: 16 11 19 13 10 25
7: 17 17 15 27 26 24
8: 12 23 24 28 24 15
9: 11 21 25 15 18 25
10: 12 14 25 11 13 29
11: 16 12 11 21 19 28
12: 18 16 20 17 15 11
13: 13 18 11 23 23 18
14: 29 16 29 10 22 28
15: 13 15 24 24 28 26
16: 28 26 13 27 18 27
17: 10 29 18 15 24 29
18: 24 24 27 24 21 12
19: 10 28 12 11 27 25
20: 12 21 28 27 11 14
21: 19 17 11 18 25 23
22: 19 21 10 21 20 22
23: 18 29 12 15 28 22
24: 25 16 15 23 27 21
25: 28 16 11 10 24 23
26: 29 19 22 20 28 27
27: 16 21 17 16 25 15
28: 11 23 17 19 27 13
29: 12 15 18 16 26 14
After (30x6):
0: 29 16 29 10 22 28
1: 28 16 11 10 24 23
2: 12 14 25 11 13 29
3: 10 28 12 11 27 25
4: 16 11 19 13 10 25
5: 21 11 19 15 13 15
6: 11 21 25 15 18 25
7: 16 22 10 15 23 29
8: 10 29 18 15 24 29
9: 18 29 12 15 28 22
10: 16 21 17 16 25 15
11: 12 15 18 16 26 14
12: 18 16 20 17 15 11
13: 19 17 11 18 25 23
14: 11 23 17 19 27 13
15: 17 18 10 20 15 24
16: 29 19 22 20 28 27
17: 16 12 11 21 19 28
18: 19 21 10 21 20 22
19: 13 18 11 23 23 18
20: 29 29 24 23 26 28
21: 25 16 15 23 27 21
22: 24 24 27 24 21 12
23: 13 15 24 24 28 26
24: 25 18 29 25 12 18
25: 12 21 28 27 11 14
26: 28 26 13 27 18 27
27: 27 22 16 27 19 24
28: 17 17 15 27 26 24
29: 12 23 24 28 24 15
Итак, это не яснодля меня в чем ваша проблема.
Пересмотренный код
Вот упрощенная версия кода, использующая более простую функцию copy_row()
, которую можно при желании обновить до memmove()
или memcpy()
вместо наличия в теле цикла.
#include <stdio.h>
#include <stdlib.h>
enum { NUM_VALUES = 6 };
static int sortedArray[][NUM_VALUES]; // Forward declaration
static void copy_row(int source[NUM_VALUES], int target[NUM_VALUES])
{
for (int i = 0; i < NUM_VALUES; i++)
target[i] = source[i];
}
static void bubbleSort(int arraySize)
{
int tempEntry[6];
for (int i = 0; i < arraySize - 1; i++)
{
for (int j = 0; j < arraySize - 1 - i; j++)
{
if ((sortedArray[j][3] > sortedArray[j + 1][3]) ||
(sortedArray[j][3] == sortedArray[j + 1][3] &&
sortedArray[j][4] > sortedArray[j + 1][4]))
{
copy_row(sortedArray[j], tempEntry);
copy_row(sortedArray[j+1], sortedArray[j]);
copy_row(tempEntry, sortedArray[j+1]);
}
}
}
}
static void print_array(const char *tag, size_t size, int data[size][NUM_VALUES])
{
printf("%s (%zux%d):\n", tag, size, NUM_VALUES);
for (size_t i = 0; i < size; i++)
{
printf("%3zu:", i);
for (int j = 0; j < NUM_VALUES; j++)
printf(" %3d", data[i][j]);
putchar('\n');
}
}
static int sortedArray[][NUM_VALUES] =
{
// random -n 30 -T '%d %d %d %d %d %d' 10 29 |
// commalist -n 6 -B 4 -b '{ ' -w -W 3 -T ' },'
{ 25, 18, 29, 25, 12, 18, },
{ 29, 29, 24, 23, 26, 28, },
{ 16, 22, 10, 15, 23, 29, },
{ 27, 22, 16, 27, 19, 24, },
{ 17, 18, 10, 20, 15, 24, },
{ 21, 11, 19, 15, 13, 15, },
{ 16, 11, 19, 13, 10, 25, },
{ 17, 17, 15, 27, 26, 24, },
{ 12, 23, 24, 28, 24, 15, },
{ 11, 21, 25, 15, 18, 25, },
{ 12, 14, 25, 11, 13, 29, },
{ 16, 12, 11, 21, 19, 28, },
{ 18, 16, 20, 17, 15, 11, },
{ 13, 18, 11, 23, 23, 18, },
{ 29, 16, 29, 10, 22, 28, },
{ 13, 15, 24, 24, 28, 26, },
{ 28, 26, 13, 27, 18, 27, },
{ 10, 29, 18, 15, 24, 29, },
{ 24, 24, 27, 24, 21, 12, },
{ 10, 28, 12, 11, 27, 25, },
{ 12, 21, 28, 27, 11, 14, },
{ 19, 17, 11, 18, 25, 23, },
{ 19, 21, 10, 21, 20, 22, },
{ 18, 29, 12, 15, 28, 22, },
{ 25, 16, 15, 23, 27, 21, },
{ 28, 16, 11, 10, 24, 23, },
{ 29, 19, 22, 20, 28, 27, },
{ 16, 21, 17, 16, 25, 15, },
{ 11, 23, 17, 19, 27, 13, },
{ 12, 15, 18, 16, 26, 14, },
};
enum { NUM_ROWS = sizeof(sortedArray) / sizeof(sortedArray[0]) };
int main(void)
{
print_array("Before", NUM_ROWS, sortedArray);
bubbleSort(NUM_ROWS);
print_array("After", NUM_ROWS, sortedArray);
return 0;
}
При одинаковых входных данных (и коде печати и т. Д.) Он дает тот же ответ.Я не проверял формально свойства сохранения - все строки, которые присутствуют в несортированных данных, присутствуют в отсортированных данных.
Нетрудно пересмотреть этот код, чтобы отсортировать массивпередается в функцию сортировки как параметр, а не как переменная области видимости файла.Это гораздо более мощная и более легкая в использовании версия кода.
Вы можете найти код в моем репозитории SOQ (Stack Overflow Questions) на GitHub в виде файлов sort31.c
(код из вопроса), sort67.c
(передача массива в качестве аргумента для сортировки) и sort89.c
(код выше) в подкаталоге src / so-5380-3837 .