Java中的Mergesort算法
我尝试用Java编写了一个合并排序算法:Java中的Mergesort算法,java,sorting,mergesort,Java,Sorting,Mergesort,我尝试用Java编写了一个合并排序算法: static void merge(int[] sort, int l, int m, int r) { int[] cache_array = new int[r - l + 1]; int l_cache = l; int _mid = m + 1; for (int i = 0; i < r - l + 1; i++) { if (l > m) { cache_ar
static void merge(int[] sort, int l, int m, int r) {
int[] cache_array = new int[r - l + 1];
int l_cache = l;
int _mid = m + 1;
for (int i = 0; i < r - l + 1; i++) {
if (l > m) {
cache_array[i] = sort[_mid];
_mid++;
} else { if (_mid > r) {
cache_array[i] = sort[l];
l++;
} else { if (sort[l] >= sort[_mid]) {
cache_array[i] = sort[l];
l++;
} else { if (sort[_mid] > sort[l]) {
cache_array[i] = sort[_mid];
_mid++;
}}}}
}
for (int i = 0; i < cache_array.length; i++) {
sort[i + l_cache] = cache_array[i];
}
}
static void mergeSort(int[] sort, int l, int r) {
if (l < r) {
int mid = (int)Math.floor((l + r - 1) / 2);
mergeSort(sort, l, mid);
mergeSort(sort, mid + 1, r);
merge(sort, l, mid, r);
}
}
public static void main(String[] args) {
int[] a = { 2, 1, 4, 5, 73, 74, 7, 5, 64, 2 };
mergeSort(a, 0, a.length - 1);
for (int i : a) {
System.out.println(i);
}
}
但它只是对数组的一部分进行排序,并用零替换其余部分。我试图将cache_数组更改为LinkedList,但没有任何更改,在尝试调试之后,我也找不到任何内容。
如果您能帮助我和/或向我展示另一种适用于Java的Mergesort算法,我将不胜感激。
我使用这个算法是因为它适用于Python,所以我想在Java中使用类似的代码,这就是我编写mergesort算法的方式
public static int[] mergeSort(int[] sort) {
if(sort.length > 1) {
int mid = sort.length / 2;
int[] left = Arrays.copyOf(sort, mid);
int[] right = Arrays.copyOfRange(sort, mid, sort.length);
// sort the left and right arrays
mergeSort(left);
mergeSort(right);
// Merge the arrays
merge(sort, left, right);
}
}
private static void merge(int[] sort, int[] leftArray, int[] rightArray) {
// These values are just to keep track of our position in each of the 3
// arrays
int l = 0; // left array
int r = 0; // right array
int o = 0; // the actual array being sorted
while(l < leftArray.length && r < rightArray.length) {
if(leftArray[l] < righArray[r]) {
sort[o++] = leftArray[l++];
}
else {
sort[o++] = leftArray[r++];
}
}
// Now that we are out of the while loop we know that either the
// left or right array has all of its values in sort, so we just
// need to put the rest of the values in the array that doesn't have
// all of its elements in sort with the following code.
while(l < leftArray.length) {
sort[o++] = leftArray[l++];
}
while(r < rightArray.length) {
sort[o++] = rightArray[r++];
}
}
这就是我编写mergesort算法的方式
public static int[] mergeSort(int[] sort) {
if(sort.length > 1) {
int mid = sort.length / 2;
int[] left = Arrays.copyOf(sort, mid);
int[] right = Arrays.copyOfRange(sort, mid, sort.length);
// sort the left and right arrays
mergeSort(left);
mergeSort(right);
// Merge the arrays
merge(sort, left, right);
}
}
private static void merge(int[] sort, int[] leftArray, int[] rightArray) {
// These values are just to keep track of our position in each of the 3
// arrays
int l = 0; // left array
int r = 0; // right array
int o = 0; // the actual array being sorted
while(l < leftArray.length && r < rightArray.length) {
if(leftArray[l] < righArray[r]) {
sort[o++] = leftArray[l++];
}
else {
sort[o++] = leftArray[r++];
}
}
// Now that we are out of the while loop we know that either the
// left or right array has all of its values in sort, so we just
// need to put the rest of the values in the array that doesn't have
// all of its elements in sort with the following code.
while(l < leftArray.length) {
sort[o++] = leftArray[l++];
}
while(r < rightArray.length) {
sort[o++] = rightArray[r++];
}
}
代码中的错误很难发现: merge函数中的循环从0迭代i到r-l+1 excluded,如果在循环期间r和l保持不变,这是正确的,但是每次从左半部分复制时都会增加l,从而减少迭代次数。因此,循环提前退出,将cache_数组中的其余元素保留为默认值0。 代码中存在多个混淆源: 在切片中包含r的约定令人困惑:它需要+1/-1调整来计算切片长度和中间索引。 使用Math.floor是无用的:整数算术在java中使用整数除法。 增加l和m参数会令人困惑,因为如果值更改,这些参数将失去其意义。使用其他索引变量遍历数组。 在else和if关键字之间添加{会引入不必要的缩进级别。 最后一个条件与前一个条件相反:您应该忽略它。请注意,如果数组元素是浮点值,则对于NaN值,这两个条件都可能为false,cache_数组的某些元素将保持不变。在这种情况下,最后一个条件将导致错误。 以下是修改后的版本: //合并“sort”数组的相邻切片。 //左切片包含从'l'到'm'的元素 //右切片包含从'm'到'r'的元素 静态void mergeint[]排序,int l,int m,int r{ int len=r-l; int[]缓存_数组=新int[len]; 对于int i=0,ll=l,mm=m;i
代码中的错误很难发现: merge函数中的循环从0到r进行迭代-l+1 excluded,如果在循环期间r和l保持不变,这是正确的,但是每次从左半部分复制时,都会增加l,从而减少迭代次数。因此,循环提前退出,将cache_数组中的剩余元素保留为默认值e 0。 代码中存在多个混淆源: 在切片中包含r的约定令人困惑:它需要+1/-1调整来计算切片长度和中间索引。 使用Math.floor是无用的:整数算术在java中使用整数除法。 增加l和m参数会让人困惑,因为如果值更改,这些参数将失去意义。请使用其他索引变量在数组中进行迭代。 在else和if关键字之间添加{会引入不必要的缩进级别。 最后一个条件与前一个条件相反:您应该忽略它。请注意,如果数组元素是浮点值,则对于NaN值,这两个条件都可能为false,cache_数组的某些元素将保持不变。在这种情况下,最后一个条件将导致错误。 以下是修改后的版本: //合并“sort”数组的相邻切片。 //左切片包含从'l'到'm'的元素 //右切片包含从'm'到'r'的元素 静态void mergeint[]排序,int l,int m,int r{ int len=r-l; int[]缓存_数组=新int[len]; 对于int i=0,ll=l,mm=m;i
我通常是这样实现的:
/// <summary>
/// Mergesort
/// best-case: O(n* log(n))
/// average-case: O(n* log(n))
/// worst-case: O(n* log(n))
/// </summary>
/// <returns>The sorted array.</returns>
/// <param name="array">array.</param>
public static int[] MergeSort(int[] array) {
// Exit condition for recursion
if (array.length <= 1) return array;
// Middle index of list to sort
int m = array.length / 2;
// Define left and right sub-listså
int[] left_array = new int[m];
int[] right_array = new int[array.length - m];
// Initialize left list
for (int i = 0; i < m; i++) left_array[i] = array[i];
// Initialize right list
for (int i = m, x = 0; i < array.length; i++, x++) right_array[x] = array[i];
// Recursively sort left half of the list
left_array = MergeSort(left_array);
// Recursively sort right half of the list
right_array = MergeSort(right_array);
// Merge sorted sub-lists
return Merge(left_array, right_array);
}
/// <summary>
/// Merge the specified left_array and right_array.
/// </summary>
/// <returns>The merge.</returns>
/// <param name="left_array">Left array.</param>
/// <param name="right_array">Right array.</param>
public static int[] Merge(int[] left_array, int[] right_array) {
int[] m = new int[left_array.length + right_array.length];
int index_l = 0;
int nl, nr;
nl = left_array.length - 1;
nr = right_array.length - 1;
for (int i = 0; i <= nl + nr + 1; i++) {
if (index_l > nl) {
m[i] = (right_array[i - index_l]);
continue;
}
if (index_l < i - nr) {
m[i] = (left_array[index_l]);
index_l++;
continue;
}
if (left_array[index_l] <= (right_array[i - index_l])) {
m[i] = (left_array[index_l]);
index_l++;
} else {
m[i] = (right_array[i - index_l]);
}
}
return m;
}
几个月前,我写了所有常见的排序算法,这就是我得到的。有点不准确,但只是为了看看这个实现如何执行。
要实现降序,我认为您只需交换比较运算符
我通常是这样实现的:
/// <summary>
/// Mergesort
/// best-case: O(n* log(n))
/// average-case: O(n* log(n))
/// worst-case: O(n* log(n))
/// </summary>
/// <returns>The sorted array.</returns>
/// <param name="array">array.</param>
public static int[] MergeSort(int[] array) {
// Exit condition for recursion
if (array.length <= 1) return array;
// Middle index of list to sort
int m = array.length / 2;
// Define left and right sub-listså
int[] left_array = new int[m];
int[] right_array = new int[array.length - m];
// Initialize left list
for (int i = 0; i < m; i++) left_array[i] = array[i];
// Initialize right list
for (int i = m, x = 0; i < array.length; i++, x++) right_array[x] = array[i];
// Recursively sort left half of the list
left_array = MergeSort(left_array);
// Recursively sort right half of the list
right_array = MergeSort(right_array);
// Merge sorted sub-lists
return Merge(left_array, right_array);
}
/// <summary>
/// Merge the specified left_array and right_array.
/// </summary>
/// <returns>The merge.</returns>
/// <param name="left_array">Left array.</param>
/// <param name="right_array">Right array.</param>
public static int[] Merge(int[] left_array, int[] right_array) {
int[] m = new int[left_array.length + right_array.length];
int index_l = 0;
int nl, nr;
nl = left_array.length - 1;
nr = right_array.length - 1;
for (int i = 0; i <= nl + nr + 1; i++) {
if (index_l > nl) {
m[i] = (right_array[i - index_l]);
continue;
}
if (index_l < i - nr) {
m[i] = (left_array[index_l]);
index_l++;
continue;
}
if (left_array[index_l] <= (right_array[i - index_l])) {
m[i] = (left_array[index_l]);
index_l++;
} else {
m[i] = (right_array[i - index_l]);
}
}
return m;
}
几个月前,我写了所有常见的排序算法,这就是我得到的。有点不准确,但只是为了看看这个实现如何执行。
要实现降序,我认为您只需交换比较运算符
您的建议无助于OP识别其代码中的错误。此外,您的代码尝试按升序排序数组,而OP则按降序排序。mergeSort的原型应该是public static void mergeSortint[]sort,或者您应该返回sort。此外,merge中if语句的else分支应该从rightArray而不是leftArray复制。您的建议不能帮助OP识别代码中的错误。此外,您的代码尝试按升序排序数组,而OP则按降序排序。mergeSort的原型应该是public static void mergeSortint[]sort,或者您应该返回sort。此外,merge中if语句的else分支应该从rightArray复制,而不是从leftArray复制。您的代码实现了一种不同的方法:OP对数组进行原地排序,而您的代码生成一个新的排序数组,并保留原始数组不变,只有一个或没有元素的数组除外。还要注意,您的方法需要ON.logN额外的空间,这是不必要的。额外的空间应该足够了。哦,那我收回我的答案!您的代码实现了一种不同的方法:OP对数组进行就地排序,而您的代码生成一个新的排序数组,并保留原始数组不变,只有一个或没有元素的数组除外。还要注意,您的方法需要ON.logN额外的空间,这是不必要的。额外的空间应该足够了。哦,那我收回我的答案!谢谢你详细的回答。我可以纠正代码,现在它工作了!谢谢你详细的回答。我可以纠正代码,现在它工作了!