英文:
Merge sort recursion trouble
问题
I've been trying to make a merge sort and I got the merging part down, it's just the recursive splitting that I'm having a little trouble with. The left and right lists are getting merged and sorted individually and not carrying over between each recursive pass. I'm not sure what I'm doing wrong with the recursion or how to fix it without scrapping the entire division method.
public static int[] mergeSort(int[] x)
{
divide(x);
return sorted;
}
public static void divide(int[] x)
{
int midP;
if((x.length/2f) == 1.5f) //the left side of the list will always be larger
midP = 2;
else
midP = x.length/2;
if(midP == 0) //if the list contains one number end
return;
System.out.println("mid: " + midP);
int[] left = new int[midP];
int[] right = new int[x.length - midP];
for(int i = 0; i < midP; i++) //fills the left list
left[i] = x[i];
for(int i = midP; i < x.length; i++) //fills the right list
right[i-midP] = x[i];
divide(left);
divide(right);
sorted = merge(left, right);
}
public static int[] merge(int[] x, int[] y)
{
int[] mergedList = new int[x.length + y.length];
int counter = 0, xCounter = 0, yCounter = 0, high = 0;
while(xCounter < x.length && yCounter < y.length)
{
printArray(x);
printArray(y);
System.out.println("checking: " + x[xCounter] + " " + y[yCounter]);
if(x[xCounter] < y[yCounter])
{
mergedList[counter] = x[xCounter];
high = y[yCounter];
if(xCounter != x.length)
xCounter++;
}
else
{
mergedList[counter] = y[yCounter];
high = x[xCounter];
if(yCounter != y.length)
yCounter++;
}
counter++;
}
mergedList[counter] = high;
return mergedList;
}
public static void printArray(int[] x)
{
System.out.print("list: ");
for(int i = 0; i < x.length; i++)
System.out.print(x[i] + " ");
System.out.println();
}
英文:
I've been trying to make a merge sort and I got the merging part down, it's just the recursive splitting that I'm having a little trouble with. The left and right lists are getting merged and sorted individually and not carrying over between each recursive pass. I'm not sure what I'm doing wrong with the recursion or how to fix it without scrapping the entire division method.
public static int[] mergeSort(int[] x)
{
divide(x);
return sorted;
}
public static void divide(int[] x)
{
int midP;
if((x.length/2f) == 1.5f) //the left side of the list will always be larger
midP = 2;
else
midP = x.length/2;
if(midP == 0) //if the list contains one number end
return;
System.out.println("mid: " + midP);
int[] left = new int[midP];
int[] right = new int[x.length - midP];
for(int i = 0; i < midP; i++) //fills the left list
left[i] = x[i];
for(int i = midP; i < x.length; i++) //fills the right list
right[i-midP] = x[i];
divide(left);
divide(right);
sorted = merge(left, right);
}
public static int[] merge(int[] x, int[] y)
{
int[] mergedList = new int[x.length + y.length];
int counter = 0, xCounter = 0, yCounter = 0, high = 0;
while(xCounter < x.length && yCounter < y.length)
{
printArray(x);
printArray(y);
System.out.println("checking: " + x[xCounter] + " " + y[yCounter]);
if(x[xCounter] < y[yCounter])
{
mergedList0+网站访问量 = x[xCounter];
high = y[yCounter];
if(xCounter != x.length)
xCounter++;
}
else
{
mergedList0+网站访问量 = y[yCounter];
high = x[xCounter];
if(yCounter != y.length)
yCounter++;
}
counter++;
}
mergedList0+网站访问量 = high;
return mergedList;
}
public static void printArray(int[] x)
{
System.out.print("list: ");
for(int i = 0; i < x.length; i++)
System.out.print(x[i] + " ");
System.out.println();
}
答案1
得分: 0
使用递归方法时,像sorted
这样的静态或实例变量使用起来比较棘手。问题在于,sorted
在递归调用中会被设置和重置,很难预测在任何给定时间它的值会是什么。如果只使用局部变量,递归函数会更容易理解。所以,修改你的divide
函数,让它返回已排序的数组,并使用递归调用的返回值:
public static int[] divide(int[] x) {
... 你现有的分割逻辑 ...
int[] leftSorted = divide(left);
int[] rightSorted = divide(right);
return merge(leftSorted, rightSorted);
}
不要忘记同时修改主入口点:
public static int[] mergeSort(int[] x) {
return divide(x);
}
在merge
方法中,似乎仍然存在一个错误:
int[] x = {5, 4, 1, 2, 3};
int[] sorted = mergeSort(x);
结果是 `1 2 3 4 0`
英文:
When using recursive methods, it's tricky to use static or instance variables like sorted
in this case. What's happening is that sorted
gets set and reset over the recursive calls, and it can be difficult to predict what its value will be at any given time. Recursive functions are easier to understand if you only use local variables. So change your divide
function so that it returns the sorted array, and use the return value from the recursive calls:
public static int[] divide(int[] x) {
... your existing divide logic ...
int[] leftSorted = divide(left);
int[] rightSorted = divide(right);
return merge(leftSorted, rightSorted);
}
Don't forget to also change the main entry point:
public static int[] mergeSort(int[] x) {
return divide(x);
}
You seem to still have a bug in the merge
method:
int[] x = {5, 4, 1, 2, 3};
int[] sorted = mergeSort(x);
results in 1 2 3 4 0
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论