微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

程序仍处于无限递归

如何解决程序仍处于无限递归

我正在尝试使用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];

解决方法

您的代码中存在三个主要问题。

  1. 您要尝试适配的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];
       ...
    
  2. 在GfG代码执行int m = (l + r) / 2的地方,结果四舍五入。这需要在Mathematica中明确完成:middle = Floor[(left + right)/2]。否则,您将获得无限递归。

  3. 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 举报,一经查实,本站将立刻删除。