我正在设置合并排序来对我的数组进行排序。目的是对任意长度的数组进行排序。
我尝试查看mergesort函数,但没有看到任何错误。该排序适用于某些数组长度,无论是奇数还是偶数,但对于数组长度(例如10),我得到了一个超限异常。
import java.util.Arrays;
class MergeSort
{
// Merge two sorted sub-arrays A[from .. mid] and A[mid + 1 .. to]
public static void merge(int[] A, int[] temp, int from, int mid, int to)
{
int k = from, i = from, j = mid + 1;
// loop till there are elements in the left and right runs
while (i <= mid && j <= to) {
if (A[i] < A[j]) {
temp[k++] = A[i++];
} else {
temp[k++] = A[j++];
}
}
// Copy remaining elements
while (i <= mid) {
temp[k++] = A[i++];
}
// Don't need to copy second half
// copy back to the original array to reflect sorted order
for (i = from; i <= to; i++) {
A[i] = temp[i];
}
}
// Iteratively sort array A[low..high] using temporary array
public static void mergesort(int[] A)
{
int low = 0;
int high = A.length - 1;
// sort array A[] using temporary array temp
int[] temp = Arrays.copyOf(A, A.length);
// divide the array into blocks of size m
// m = [1, 2, 4, 8, 16...]
for (int m = 1; m <= high - low; m = 2*m)
{
// for m = 1, i = 0, 2, 4, 6, 8...
// for m = 2, i = 0, 4, 8, 12...
// for m = 4, i = 0, 8, 16...
// ...
for (int i = low; i < high; i += 2*m)
{
int from = i;
int mid = i + m - 1;
int to = Integer.min(i + 2 * m - 1, high);
merge(A, temp, from, mid, to);
}
}
}
// Iterative Implementation of Mergesort algorithm
public static void main(String[] args)
{
int[] A = { 5, 7, -9, 3, -4, 2, 8, 8, 10, 11 };
System.out.println("Original Array : " + Arrays.toString(A));
mergesort(A);
System.out.println("Modified Array : " + Arrays.toString(A));
}
}
答案 0 :(得分:1)
您的中间计算不正确。有时您将其设置在区域范围之外。
此以下更改通过防止中点超出范围来修复算法,类似于您对防止to超出范围所做的操作。
将int mid = i + m - 1;
更改为int mid = Math.min(i + m - 1, A.length - 1);
说明:如您的评论中所述,您正在检查的区域切片正在增大。所以这是数组的排序方式,何时发生越界错误,以及为什么在以2的幂为单位的大小上未发生此错误?
[ -9, 5, 7, 3, -4, 2, 8, 8, 10, 11 ] Array size
First pass: [] [] [] [] [] [] [] [] [] [] 1
Second: [ ] [ ] [ ] [ ] [ ] 2
Third: [ ] [ ] [ ERROR] 4
答案 1 :(得分:0)
这是您的解决方法:
为您的中部添加了一个if语句,使其不会越过数组边界
if(mid<high) {
merge(A, temp, from, mid, to);
}
完整代码:
// Merge two sorted sub-arrays A[from .. mid] and A[mid + 1 .. to]
public static void merge(int[] A, int[] temp, int from, int mid, int to)
{
int k = from, i = from, j = mid + 1;
// loop till there are elements in the left and right runs
while (i <= mid && j <= to) {
if (A[i] < A[j]) {
temp[k++] = A[i++];
} else {
temp[k++] = A[j++];
}
}
// Copy remaining elements
while (i <= mid) {
temp[k++] = A[i++];
}
// Don't need to copy second half
// copy back to the original array to reflect sorted order
for (i = from; i <= to; i++) {
A[i] = temp[i];
}
}
// Iteratively sort array A[low..high] using temporary array
public static void mergesort(int[] A)
{
int low = 0;
int high = A.length - 1;
// sort array A[] using temporary array temp
int[] temp = Arrays.copyOf(A, A.length);
//System.out.println("temp Array : " + Arrays.toString(temp));
// divide the array into blocks of size m
// m = [1, 2, 4, 8, 16...]
for (int m = 1; m <= high - low; m = 2*m)
{
// for m = 1, i = 0, 2, 4, 6, 8...
// for m = 2, i = 0, 4, 8, 12...
// for m = 4, i = 0, 8, 16...
// ...
for (int i = low; i < high; i += 2*m)
{
int from = i;
int mid = i + m - 1;
int to = Integer.min(i + 2 * m - 1, high);
if(mid<high) {
merge(A, temp, from, mid, to);
}
}
}
}
// Iterative Implementation of Mergesort algorithm
public static void main(String[] args)
{
int[] A = { 5, 7, -9, 3, -4, 2, 8, 8, 10, 11 };
System.out.println("Original Array : " + Arrays.toString(A));
mergesort(A);
System.out.println("Modified Array : " + Arrays.toString(A));
}