отсортировать двухмерный массив методом обмена от меньшего к большему c/c++
все исправно работает со знаком "меньше"
как только меняю его, пропадает один элемент.
буду благодарен за помощь!
#include <iostream>
int main()
{
const int a = 7; const int b = 7;
double arr[a][b];
double fl, temp;
for(int i = 0;i != a;i++)
for(int j=0; j!=b; j++)
arr[i][j] = 10 + rand() % (999 - 10 + 1) / 10.;
do
{
fl = 0;
for (int j = 6; j != -1; j--) {
for (int i = 6; i != -1; i--) {
if (arr[i][j - 1] < arr[i][j]) {
temp = arr[i][j];
arr[i][j] = arr[i][j - 1];
arr[i][j - 1] = temp;
fl = 1;
}
}
}
} while (fl);
for (int i = 0; i < a; i++) {
for (int j = 0; j < b; j++)
printf("%.02lf ", arr[i][j]);
printf("\n");
}
return 0;
}
Ответы (1 шт):
Вообще-то у вас тут неопределенное поведение, связанное с выходом за пределы массива. Когда j==0, вы обращаетесь к элементу с отрицательным индексом arr[i][-1].
for (int j = 6; j != -1; j--) // когда j==0
for (int i = 6; i != -1; i--)
if (arr[i][j - 1] < arr[i][j]) // здесь получается arr[i][-1]
{
temp = arr[i][j];
arr[i][j] = arr[i][j - 1]; // здесь получается arr[i][-1]
arr[i][j - 1] = temp; // здесь получается arr[i][-1]
fl = 1;
}
Написанный вами алгоритм нерабочий.
Общая сортировка срабатывает как раз из-за ошибки с выходом за пределы массива и тем, что неопределенное поведение не вызывает краха программы, пока вы не выходите за пределы общего куска памяти, занимаемого двумерным массивом (который в памяти хранится как одномерный). Потому что сейчас, когда вы оперируете if (arr[2][-1] < arr[2][0]), по по факту получается, что вы сравниваете if (arr[1][6] < arr[2][0]).
Если вы исправите ошибку с выходом за пределы массива, у вас перестанет работать сортировка.
Ну и да - лишнее значение появляется если случайное число, находящееся в памяти перед первым элементом массива меньше первого элемента массива arr[0][-1] < arr[0][0]. А вообще может не число пропасть а программа упасть.
В принципе, чтобы исправить вам нужно убрать выход за границы массива и после вложенных циклов поставить ещё один цикл, который сравнивает и меняет местами если надо последний элемент предыдущей строки с первым элементом следующей строки.
И замечание - вы же задали размеры массива константами const int a = 7; const int b = 7; Почему в циклах вы пользуетесь не ими, а магическими числами?
for (int j = 6; j != -1; j--)
for (int i = 6; i != -1; i--)
// должно быть
for (int j = b-1; j != -1; j--)
for (int i = a-1; i != -1; i--)
Второе замечание - зачем массив типа double, если вы его заполняете целыми значениями?
Вы написали пузырьковую сортировку. Если вы будете обращаться с двумерным массивом как с одномерным, то пузырьковую сортировку можно оптимизировать - на каждом шаге внешнего цикла внутренний цикл будет делать на одну итерацию меньше, т.к. одно число уже заняло свою позицию и повторно проверять его не нужно.
Чтобы обращаться с двумерным массивом как с одномерным есть два варианта:
- рассматривать ваш двумерный массив
arr[a][b]как одномерныйarr[a*b]- но это по стандартуС++- неопределенное поведение, хотя оно будет работать корректно покаС++обеспечивает обратную совместимость сC(приблизительно :) ) - рассчитывать индексы двумерного массива
iиjотносительно индекса элемента в одномерном массиве
