[英]How can I implement MergeSort with bound inclusive to exclusive?
我正在尝试在 Java 中实现 MergeSort 算法,以便它从A[start..end]
对数组进行排序。 我真的很难实现它,以便它不包括在合并中传入的最后一个索引。 我正在尝试跟踪我的代码,但一直感到困惑。
这是我的代码:
public class MergeSort {
public static void main(String[] args) {
int[] list = new int[] { 3, 7, 5, 2, 9 };
int[] result = mergeSort(list, 0, list.length);
System.out.print("[");
for (int i = 0; i < result.length; i++) {
System.out.print(" " + result[i]);
}
System.out.println("]");
}
public static int[] mergeSort(int[] list, int start, int end) {
if (end - start < 2) {
return list;
} else {
int mid = (start + end) / 2;
mergeSort(list, start, mid);
mergeSort(list, mid + 1, end);
merge(list, start, mid, end);
return list;
}
}
public static void merge(int[] list, int start, int mid, int end) {
int[] copy = new int[list.length];
for (int i = 0; i < list.length; i++) {
copy[i] = list[i];
}
int i = start;
int k = start;
int j = mid + 1;
while (i <= mid && j <= end) {
if (copy[i] <= copy[j]) {
list[k] = copy[i];
i++;
} else {
list[k] = copy[j];
j++;
}
k++;
}
while (i <= mid) {
list[k] = copy[i];
i++;
k++;
}
while (j < end) {
list[k] = copy[j];
j++;
k++;
}
}
}
要么调用mergeSort(list, 0, list.length - 1);
或者打电话给助手 function 让我们说F
。 因此,例如,您将调用F(list, 0, list.length);
F
唯一会做的就是调用mergeSort(list, 0, list.length - 1);
.
这样你就不用mergeSort
了。 你只需打电话给F
。
编辑:
public class MergeSort {
public static void main(String[] args) {
int[] list = new int[] {3, 7, 5, 2, 9};
int[] result = mergeSort(list, 0, list.length);
System.out.print("[");
for (int i = 0; i < result.length; i++) {
System.out.print(" " + result[i]);
}
System.out.println("]");
}
public static int[] mergeSort(int[] list, int start, int end) {
return F(list, start, end - 1);
}
public static int[] F(int[] list, int start, int end) {
if (end - start < 2) {
return list;
} else {
int mid = (start + end) / 2;
F(list, start, mid);
F(list, mid + 1, end);
merge(list, start, mid, end);
return list;
}
}
public static void merge(int[] list, int start, int mid, int end) {
int[] copy = new int[list.length];
for (int i = 0; i < list.length; i++) {
copy[i] = list[i];
}
int i = start;
int k = start;
int j = mid + 1;
while (i <= mid && j <= end) {
if (copy[i] <= copy[j]) {
list[k] = copy[i];
i++;
} else {
list[k] = copy[j];
j++;
}
k++;
}
while (i <= mid) {
list[k] = copy[i];
i++;
k++;
}
while (j < end) {
list[k] = copy[j];
j++;
k++;
}
}
}
使用包含start
和end
定义的切片调用mergesort
确实是一种明智的方法,因为调用序列更简单: merge(array, 0, array.length)
并且它允许空切片,这对于空 arrays 是必需的。
您的mergesort
方法有一个错误:右切片从mid
开始并在 end 之前end
,因此调用应该是mergeSort(list, mid, end);
merge
方法也存在问题:
list
,而应仅复制start
的end
(排除)。 如果您合并到临时数组中并在合并后将其复制回来,则更简单。 使用这种方法,您可以在左侧部分用尽时停止合并,因为右侧部分的剩余值已经在正确的位置。<
运算符而不是<=
。这是一个更正的版本:
public class MergeSort {
public static void main(String[] args) {
int[] list = new int[] { 3, 7, 5, 2, 9 };
int[] result = mergeSort(list, 0, list.length);
System.out.print("[");
for (int i = 0; i < result.length; i++) {
System.out.print(" " + result[i]);
}
System.out.println(" ]");
}
public static int[] mergeSort(int[] list, int start, int end) {
if (end - start < 2) {
return list;
} else {
// compute the mid point:
// the left part spans from start included to mid excluded
// the right part spans from mid included to end excluded
// avoid adding start and end to prevent overflow overflow for very large arrays
int mid = start + (end - start) / 2;
mergeSort(list, start, mid);
mergeSort(list, mid, end);
merge(list, start, mid, end);
return list;
}
}
public static void merge(int[] list, int start, int mid, int end) {
int[] temp = new int[end - start];
int k = 0; // index into the temporary array
int i = start; // index into the left part, stop at mid
int j = mid; // index into the right part, stop at end
// select from left or right slices and store into the temp array
while (i < mid && j < end) {
if (list[i] <= list[j]) {
temp[k++] = list[i++];
} else {
temp[k++] = list[j++];
}
}
// copy the remaining elements from the left part
while (i < mid) {
temp[k++] = list[i++];
}
// copy the sorted elements back to the original list
for (i = 0; i < k; i++) {
list[start + i] = temp[i];
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.