Сортировка слиянием без рекурсии не будет сортировать последний элемент массива

#java #mergesort

#java #сортировка слиянием

Вопрос:

Я пытаюсь создать метод сортировки слиянием без использования рекурсии. Это почти отлично работает, за исключением того, что по какой-то причине он не сортирует последний элемент моего массива. Любая помощь приветствуется!

Пример вывода:

 [23, 94, 69, 32, 99, 20, 17, 88, 22, 88]
  

Сортировка слиянием заняла 7,134364 миллисекунды

оригинал: [17, 20, 22, 23, 32, 69, 88, 88, 94, 99] //Arrays.sort

working1: [17, 20, 22, 23, 32, 68, 88, 94, 99, 88] //MergeSort

Ошибка

 import java.util.*;

public class MergeSort {
public static void mergeSortExplicit(int[] arr, int n){
    int size;  
    int left; 

    for (size = 1; size <= n-1; size = 2*size) {  
        for (left = 0; left < n-1; left  = 2*size) { 
            int mid = left   size - 1; 

            int right = Math.min(left   2*size - 1, n-1);

            merge(arr, left, mid, right);
        } 
    } 
 }
private static void merge(int[] array, int start, int mid, int end) {
    int leftIndex = start;
    int rightIndex = mid   1;
    int[] temp = new int[end - start   1];
    int tempIndex = 0;

    while (leftIndex <= mid amp;amp; rightIndex <= end) {

        temp[tempIndex  ] = (array[leftIndex] < array[rightIndex]) ? array[leftIndex  ] : array[rightIndex  ];

    }

    if (leftIndex <= mid) {
        System.arraycopy(array, leftIndex, temp, tempIndex, mid - leftIndex   1);
    }

    if (rightIndex <= end) {
        System.arraycopy(array, rightIndex, temp, tempIndex, end - rightIndex   1);
    }

    System.arraycopy(temp, 0, array, start, end - start   1);

}

public static final void main(String[] args) {
    Random random = new Random();
    int[] original = new int[10];
    for (int i = 0; i < original.length; i  ) {
        original[i] = random.nextInt(original.length * 10);
    }
    int[] working1 = new int[original.length];
    System.arraycopy(original, 0, working1, 0, original.length);

    long startTime = 0, endTime = 0;

    startTime = System.nanoTime();
    Arrays.sort(original);
    endTime = System.nanoTime();
    System.out.println("Arrays.sort() took "   ((endTime - startTime) / 1E6)   " milliseconds");

    startTime = System.nanoTime();
    //mergeSort(working1, 0, working1.length - 1);
     System.out.println(Arrays.toString(working1));
    mergeSortExplicit(working1, working1.length - 1);
    endTime = System.nanoTime();
    System.out.println("MergeSort took "   ((endTime - startTime) / 1E6)   " milliseconds");

    if (!Arrays.equals(original, working1)) {
        System.out.println("original: "   Arrays.toString(original));
        System.out.println("Working1: "   Arrays.toString(working1));
        System.out.println("There is an error");
    } else {
        System.out.println("Sorts Work!");
    }
}

}
  

Ответ №1:

Просто просматривая, я вижу, что вы вызываете следующую функцию в main :

 mergeSortExplicit(working1, working1.length - 1);
  

это означает, что вы уже вызываете функцию с размером на 1 меньше, чем фактический размер, а затем снова внутри этой вызываемой функции в следующем цикле :

 for (size = 1; size <= n-1; size = 2*size)
  

вы снова рассматриваете на 1 меньше того, что вы передали.

Пожалуйста, удалите любое из вышеуказанных уменьшений, тогда оно должно работать нормально.

Комментарии:

1. Это было половиной проблемы, я вызвал mergeSortExplicit без длины — 1, а затем получил исключение ArrayIndexOutOfBoundsException. Чтобы исправить это, когда я инициализирую int mid, я сделал то же самое, что и для того места, где я использовал функцию Math.min(), потому что без этого Mid не проверялся, был ли он слишком большим. Спасибо за помощь!