如何解决程序仍处于无限递归
我正在尝试使用Wolfram Mathematica创建合并排序,但是我仍然遇到此递归错误,而且我不知道在哪里出错。我用Java重写了这段代码,在这里工作得很好,所以我认为对于Wolfram来说这是一件特别的事情。您有什么想法,我的代码可能有什么问题吗?
非常感谢!
这是我的代码:
mergeSort[x_,left_,right_] :=
Module[{array = x,middle,n1,n2,L,R,i,j,k},If[left < right,middle = (left + right) / 2;
mergeSort[array,left,middle];
mergeSort[array,middle + 1,right];
n1 = middle - left + 1;
n2 = right - middle;
L = {};
R = {};
For[i = 1,i < n1,++i,L[[i]] = array[[left + 1]];
];
For[j = 1,j < n2,++j,R[[j]] = array[[middle + 1 + j]];
];
i = 0;
j = 0;
k = left;
While[i < n1 && j < n2,If[L[[i]] <= R[[j]],array[[k]] = L[[i]];
i++;,array[[k]] = R[[j]];
j++;
];
k++;
];
While[i < n1,array[[k]] = L[[i]];
i++;
k++;
];
While[j < n2,array[[k]] = R[[j]];
j++;
k++;
];
Return[array];
];
]
这是我的函数调用-mergeSort[{58,3,98},3];
解决方法
您的代码中存在三个主要问题。
-
您要尝试适配的GfG代码通过引用传递了数组
arr
,因此每次递归都在同一个对象上进行。这在Mathematica中通常不会发生。我添加了HoldFirst
来传递array
by reference。一种替代方法是简单地将array
完全排除在函数调用之外,然后直接将其修改为全局变量。例如mergeSort[left_,right_] := Module[{},If[left < right,middle = Floor[(left + right)/2]; mergeSort[left,middle]; mergeSort[middle + 1,right]; ...
-
在GfG代码执行
int m = (l + r) / 2
的地方,结果四舍五入。这需要在Mathematica中明确完成:middle = Floor[(left + right)/2]
。否则,您将获得无限递归。 -
GfG代码使用从零开始的数组。 Mathematica使用基于一个的列表,因此可以将诸如
for (int i = 0; i < n1; ++i)
之类的代码更改为For[i = 1,i <= n1,++i,...
您在GfG代码L[i] = arr[l + i]
中也有此行的错字,最后您不需要在Mathematica中使用Return
来返回函数末尾的值。
Attributes[mergeSort] = HoldFirst;
mergeSort[array_Symbol,left_Integer,right_Integer] :=
Module[{middle,n1,n2,L,R,i,j,k},middle = Floor[(left + right)/2];
mergeSort[array,left,middle];
mergeSort[array,middle + 1,right];
n1 = middle - left + 1;
n2 = right - middle;
L = ConstantArray[Null,n1];
R = ConstantArray[Null,n2];
For[i = 1,L[[i]] = array[[left + i - 1]];
];
For[j = 1,j <= n2,++j,R[[j]] = array[[middle + j]];
];
i = 1;
j = 1;
k = left;
While[i <= n1 && j <= n2,If[L[[i]] <= R[[j]],array[[k]] = L[[i]];
i++;,array[[k]] = R[[j]];
j++;
];
k++;
];
While[i <= n1,array[[k]] = L[[i]];
i++;
k++;
];
While[j <= n2,array[[k]] = R[[j]];
j++;
k++;
];
array
]
]
array = {58,3,98};
mergeSort[array,1,Length[array]]
{3,58,98}
请注意,这已更改了array
的内容。
array
{3,58,98}
替代版本
在Wellin,Gaylord & Kamin中,这是Mathematica习语中更多的版本。
merge[lis_List,{}] := lis
merge[{},lis_List] := lis
merge[{a_,ra___},{b_,rb___}] :=
If[a <= b,Join[{a},merge[{b},{ra,rb}]],Join[{b},merge[{a,ra},{rb}]]]
MergeSort[{}] := {}
MergeSort[{x_}] := {x}
MergeSort[lis_List] := Module[{div = Floor[Length[lis]/2]},merge[MergeSort[Take[lis,div]],MergeSort[Drop[lis,div]]]]
MergeSort[{58,98}]
{3,58,98}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。