Сортировка двумерного массива с помощью сортировки выбором

Я использовал следующий код -

x[][] — массив для сортировки

    void sort() {
    int max1, max2, s;
    for (int i = 0; i < row; i++) {
        for (int j = 0; j < column; j++) {
            max1 = i;
            max2 = j;
            for (int k = i; k < row; k++) {
                if (k == i) {   // need to improve this part
                    for (int l = j; l < column; l++) {
                        if (x[k][l] > x[max1][max2]) {
                            max1 = k;
                            max2 = l;
                        }
                    }
                } else {
                    for (int l = 0; l < column; l++) {
                        if (x[k][l] > x[max1][max2]) {
                            max1 = k;
                            max2 = l;
                        }
                    }
                }
            }
            s = x[max1][max2];
            x[max1][max2] = x[i][j];
            x[i][j] = s;
        }
    }
}

Я хочу удалить оператор if else или это другой способ сделать это с помощью сортировки выбором?

(Я знаю, что есть более простые способы сделать это, но я пытаюсь сделать это с помощью сортировки выбором)


person antrep1234    schedule 13.06.2017    source источник
comment
Когда вы говорите, что я хочу удалить оператор if else, вы имеете в виду улучшение?   -  person RostSunshine    schedule 13.06.2017
comment
да @RostSunshine   -  person antrep1234    schedule 13.06.2017
comment
Можете ли вы дать нам больше информации. Я пытаюсь разобрать код и не понимаю, что такое переменные r и c. Можете ли вы дать мне остальную часть кода. Также у вас много вложенных циклов for, что очень плохо для эффективности.   -  person RostSunshine    schedule 13.06.2017
comment
Неважно, я вижу его строку и столбцы.   -  person RostSunshine    schedule 13.06.2017
comment
Я работаю над решением, извините за ожидание, у меня нет java, установленного на этом компе, и в настоящее время я не могу отлаживать и логику самостоятельно.   -  person RostSunshine    schedule 13.06.2017


Ответы (2)


Мне очень не нравится, как вы называете свои переменные. Я предлагаю использовать r, c в качестве префиксов для строки и столбца, v для значения, а затем использовать Outer и Inner в качестве суффиксов для двух циклов над массивом и Max для максимума.

Использование vMax увеличивает локальность памяти вашего алгоритма — избегая поиска в удаленных частях памяти, он должен выполняться немного быстрее при работе с большими массивами. Не то, чтобы сортировка выбором когда-либо была конкурентоспособной по сравнению, скажем, с быстрой сортировкой: асимптотическая сложность останется ужасной.

Это упрощает чтение:

for (int rOuter = 0; rOuter < rows; rOuter++) {
    for (int cOuter = 0; cOuter < cols; cOuter++) {
        // find max value, and swap with rOuter, cOuter            
        int rMax = rOuter;
        int cMax = cOuter;
        int vMax = x[rOuter][cOuter];
        // finish the row current row
        for (int cInner = cOuter+1; cInner < cols; cInner++) {
            if (x[rOuter][cInner] > vMax) {
                rMax = rOuter; 
                cMax = cInner; 
                vMax = x[rOuter][cInner];
            }
        }
        // evaluate remaining rows
        for (int rInner = rOuter+1; rInner < rows; rInner++) {
            for (int cInner = 0; cInner < cols; cInner++) {
                if (x[rInner][cInner] > vMax) {
                   rMax = rInner; 
                   cMax = cInner; 
                   vMax = x[rInner][cInner];
                }
            }
        }            
        // swap. No aux needed, as vMax contains value of max
        x[rMax][cMax] = x[rOuter][cOuter];
        x[rOuter][cOuter] = vMax;
    }
 }

Обратите внимание, что я удалил самое внутреннее условие: оно должно быть выполнено один раз и только один раз, чтобы закончить текущую строку перед вычислением всех оставшихся строк.

Также обратите внимание - я не тестировал этот код. Выглядит правильно, но относитесь к этому с осторожностью.

person tucuxi    schedule 13.06.2017

Как я уже упоминал, у меня сейчас нет среды для тестирования, но я считаю, что это должно сработать. Если нет, дайте мне знать, и я изменю его соответственно.

Вот мое решение:

void sort() {
 int max1, max2, count, minValue, rowHold, colHold;
 int[][] tempArr = new int[row][column]; 
 while(count != (row*column)) 
 {
    for (int i = 0; i < row; i++) 
    {
            for (int j = 0; j < column; j++) 
        {
                max1 = i;
                max2 = j;
            if(minValue>x[i][j] && x[i][j] != tempArry[i][j])
            {
                minvalue= x[i][j];
            }



        }

    }

    tempArr[rowHold][colHold] = minVlaue;
    if(colHold<column)
    {
    colHold++;
    }
    else if(colHold=column)
    {
        colHold = 0;
        rowHold++;
    }
    count++;
}   
x = tempArry;

}

Это решение выполняет сортировку выбором и во много раз более эффективно, чем ваше текущее решение. Проблема с вашим текущим решением заключается в том, что в нем слишком много вложенных циклов. Вложенные циклы создают огромные проблемы с точки зрения эффективности, поэтому вы хотите свести к минимуму их использование и глубину.

Надеюсь, это работает, прокомментируйте это, если это не так, и я это исправлю! Также любые вопросы о том, что я сделал, и я буду комментировать и объяснять, что я сделал.

person RostSunshine    schedule 13.06.2017
comment
Мне было бы очень интересно посмотреть, во много ли раз ваш код быстрее, чем OP или нет. Я готов поспорить, что после того, как вы исправите ошибки, это займет примерно столько же времени: все правильные сортировки выбора должны работать примерно одинаково. Одна очевидная ошибка заключается в том, что вы увеличиваете rowHold и colHold на каждой итерации, что приводит к раннему исключению ArrayIndexOutOfBounds. - person tucuxi; 13.06.2017
comment
@tucuxi да, они это делают, но вы можете чрезмерно усложнить их серверность, что, я бы сказал, сделал ОП с 4 вложенными циклами for, создающими хаос, где два гораздо меньше даже внутри цикла while. Он проанализировал массив дважды, и с 2D-массивами это крайне неэффективно. - person RostSunshine; 13.06.2017
comment
Это все еще не во много раз быстрее, чем код OP; внешние и внутренние циклы выполняются по строкам * столбцам, как и в случае OP (или моего), но ваш код труднее читать, чем код OP. Кроме того, вы сортируете по возрастанию, а OP сортирует по убыванию. - person tucuxi; 13.06.2017
comment
Я имею в виду, что N ^ 4 сильно отличается от N ^ 2, поэтому я бы сказал, что это много раз. А если макс то это переключатель смены имени и ‹ на ›. Так что ОП может выбрать, какой путь. Я сделал сортировку выбором, не заботясь о направлении, потому что это легко переключается. - person RostSunshine; 13.06.2017
comment
Количество поисковых запросов для сортировки массива из n элементов (n = строк x столбцов, если он двумерный; n = глубина x строк x столбцов, если трехмерный) с использованием select-sort составляет порядка n^2 (один полный внешний массив). петля, одна неполная внутренняя петля). Количество операторов for или while не имеет значения - я могу зацикливаться o(n!) раз с помощью одного цикла while. Важным числом является то, сколько раз я выполняю самый внутренний код. И это n ^ 2 в вашем коде, OP и моем. - person tucuxi; 13.06.2017
comment
@tucuxi Нет, независимо от ситуации, ОП будет зацикливать это 4 раза. - person RostSunshine; 13.06.2017
comment
Внутри вашего цикла while? запускает строки x столбцов раз. Внутри первых двух циклов for OP? также запускает строки x cols раз. Действительно, измерь. Это очень поучительно (к тому же, если бы вы были правы, это было бы фактическим доказательством ваших аргументов!) - person tucuxi; 13.06.2017