отсортировать двухмерный массив методом обмена от меньшего к большему 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 шт):

Автор решения: DmitryK

Вообще-то у вас тут неопределенное поведение, связанное с выходом за пределы массива. Когда 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 относительно индекса элемента в одномерном массиве
→ Ссылка