Моя логика сортировки вставками кажется правильной, но не работает

Я пытаюсь реализовать сортировку вставками.

public int[] insertionSort(int[] a) {

    for(int i=0; i<a.length;i++) {
        int j=i+1;

        while(a[j] < a[i] && j < a.length) {
            swap(a[j],a[i]);
            j--;
            i--;
        }
    }
    return a;
}

public void swap(int a, int b) {
    int temp;
    temp = a;
    a = b;
    b = temp;
}

Разве это технически не то же самое (с точки зрения результата вывода), как если бы я сказал j = i-1 и подставил условие в цикле while с j ‹ a.length на j >= 0?


person user2770982    schedule 06.07.2014    source источник
comment
Не работает каким образом? Можете ли вы предоставить нам пример ввода/вывода, который работает не так, как вы ожидали?   -  person Keppil    schedule 06.07.2014
comment
Извиняюсь, ArrayIndexOutOfBounds. Дважды проверил и не вижу никаких проблем с этим   -  person user2770982    schedule 07.07.2014


Ответы (1)


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

Вам, вероятно, лучше просто не использовать отдельный метод для обмена, например этот (также пришлось увеличивать вместо уменьшения значения i и j):

public int[] insertionSort(int[] a) {
    int temp;

    for(int i=0; i<a.length;i++) {
        int j=i;

        while(j > 0 && a[j-1] > a[j]) {
            temp = a[j];
            a[j] = a[j-1];
            a[j-1] = temp;
            j--;
        }
    }
    return a;
}

Редактировать: пришлось обновить снова - условия в цикле while были в неправильном порядке, поэтому он искал следующий индекс массива, прежде чем проверять, достиг ли он конца массива.

Редактировать 2. Как упоминалось в комментариях, я покажу, как написать метод swap, который действительно работает — вместо передачи значений вам придется передавать весь массив и возвращать его после. Я бы по-прежнему, вероятно, рекомендовал сделать это вышеописанным способом, но только в образовательных целях:

public int[] insertionSort(int[] a) {

    for(int i=0; i<a.length;i++) {
        int j=i;

        while(j > 0 && a[j-1] > a[j]) {
            a = swap(a, j-1, j);
            j--;
        }
    }
    return a;
}


public int[] swap(int[] a, int index1, int index2) {
    int temp = a[index1];
    a[index1] = a[index2];
    a[index2] = temp;
    return a;
}

Редактировать 3: делал что-то глупое и не совсем дал сортировку вставками. Теперь все в порядке (извините за каламбур).

person SharkofMirkwood    schedule 06.07.2014
comment
Однако код, скорее всего, по-прежнему будет выдавать исключение ArrayIndexOutOfBoundsException из-за j-- и i--. - person Simon; 06.07.2014
comment
Не проверил логику должным образом, заметив другую проблему, я решу это сейчас! - person SharkofMirkwood; 06.07.2014
comment
он мог просто передать массив и индексы методу - person Amir Afghani; 06.07.2014
comment
@AmirАфгани Да, это можно было бы сделать и таким образом, но вам придется возвращать массивы, и это кажется бессмысленным - делая это таким образом, все становится проще. - person SharkofMirkwood; 07.07.2014
comment
Вы запускали код? Я получаю исключение с массивом {5, 1, 12, 15}. - person Simon; 07.07.2014
comment
Разве я не хотел бы уменьшить вместо увеличения, потому что я хочу менять местами каждый раз, когда он выходит из строя, поскольку я приближаюсь к началу массива (индекс 0), чтобы убедиться, что меньшее значение находится слева от массива, следовательно, j--/i-- вместо j++/i++, если это имеет смысл. - person user2770982; 07.07.2014
comment
Должен ли я передавать значение, а не ссылки на значение для метода swap, потому что, когда я использую метод swap в методе insertionSort, я передаю ему целое число в этой позиции, следовательно, меняю местами a[j] и a[i]. - person user2770982; 07.07.2014
comment
@SharkofMirkwood На самом деле, это сортировка вставками, и в этом случае вам нужно уменьшить значение в этой точке. en.wikipedia.org/wiki/Insertion_sort - person Simon; 07.07.2014
comment
@SharkofMirkwood Это кажется ближе к пузырьковой сортировке и плохо сортирует все массивы. При попытке {15, 12, 1, 5} он не вышел отсортированным. - person Simon; 07.07.2014
comment
@Simon Саймон Ну, это смущает ... Я обновил его сейчас, это сортировка вставками, и я пробовал этот массив - кажется, он работает нормально. Спасибо, что указали на мою ошибку(и)! - person SharkofMirkwood; 07.07.2014
comment
@user2770982 user2770982 Теперь я это исправил, вы были правы насчет уменьшения, и я думал о другом алгоритме сортировки ... Я также объяснил, как это сделать с работающим методом swap. - person SharkofMirkwood; 07.07.2014
comment
@SharkofMirkwood Не за что. Хороший каламбур ;) PS ваш метод подкачки выдает две ошибки. - person Simon; 07.07.2014
comment
@Simon Да, еще раз спасибо - пара глупых вещей, которые были раньше, теперь должны работать. - person SharkofMirkwood; 07.07.2014
comment
Давайте продолжим обсуждение в чате. - person Simon; 07.07.2014