合并排序时出现 StackOverFlowException
StackOverFlowException on Merge Sort
所以,我正在尝试进行合并排序,但我一直收到 WhosebugException
并且我不太明白我做错了什么。此工作代码是否适用于合并排序,或者是否有更好的代码编写方法?
static public List<string> MergeSort(List<string> list)
{
List<string> left = new List<string>();
List<string> right = new List<string>();
if (list.Count <= 1)
{
return list;
}
foreach (var item in list)
{
if (list.IndexOf(item) <= (list.Count / 2))
{
left.Add(item);
}
else
right.Add(item);
}
left = MergeSort(left);
right = MergeSort(right);
return Merge(left, right);
}
static public List<string> Merge(List<string> left, List<string> right)
{
List<string> merged = new List<string>();
while (left.Count != 0 && right.Count != 0)
{
if (left.First().Length <= right.First().Length)
{
merged.Add(left.First());
left.Remove(left.First());
}
else
{
merged.Add(right.First());
right.Remove(right.First());
}
}
while(left.Count != 0)
{
merged.Add(left.First());
left.Remove(left.First());
}
while (right.Count != 0)
{
merged.Add(right.First());
right.Remove(right.First());
}
return merged;
}
您的问题在于确定将每个项目放入哪个列表的代码
if (list.IndexOf(item) <= (list.Count / 2))
如果列表有 2 个项目,则索引为 0 和 1,并且此条件对两者都成立,因此它们都放在左侧列表中,而右侧没有任何内容。然后你打电话给
left = MergeSort(left);
这是一个包含 2 个项目的列表,它再次将两者都放在左边,然后再次调用它,将它们都放在左边......永远。
只需将比较更改为
if (list.IndexOf(item) < (list.Count / 2))
此外,您不应使用 IndexOf
,因为如果您在列表中有重复项,它将 return 第一项而不是当前项的索引。因此,其中两次包含 "abc" 的列表将 return 0 两次,您将陷入同一个无限循环。相反,您可以像这样 for
循环
for (int i = 0; i < list.Count; i++)
{
if (i < (list.Count / 2))
{
left.Add(list[i]);
}
else
{
right.Add(list[i]);
}
}
所以,我正在尝试进行合并排序,但我一直收到 WhosebugException
并且我不太明白我做错了什么。此工作代码是否适用于合并排序,或者是否有更好的代码编写方法?
static public List<string> MergeSort(List<string> list)
{
List<string> left = new List<string>();
List<string> right = new List<string>();
if (list.Count <= 1)
{
return list;
}
foreach (var item in list)
{
if (list.IndexOf(item) <= (list.Count / 2))
{
left.Add(item);
}
else
right.Add(item);
}
left = MergeSort(left);
right = MergeSort(right);
return Merge(left, right);
}
static public List<string> Merge(List<string> left, List<string> right)
{
List<string> merged = new List<string>();
while (left.Count != 0 && right.Count != 0)
{
if (left.First().Length <= right.First().Length)
{
merged.Add(left.First());
left.Remove(left.First());
}
else
{
merged.Add(right.First());
right.Remove(right.First());
}
}
while(left.Count != 0)
{
merged.Add(left.First());
left.Remove(left.First());
}
while (right.Count != 0)
{
merged.Add(right.First());
right.Remove(right.First());
}
return merged;
}
您的问题在于确定将每个项目放入哪个列表的代码
if (list.IndexOf(item) <= (list.Count / 2))
如果列表有 2 个项目,则索引为 0 和 1,并且此条件对两者都成立,因此它们都放在左侧列表中,而右侧没有任何内容。然后你打电话给
left = MergeSort(left);
这是一个包含 2 个项目的列表,它再次将两者都放在左边,然后再次调用它,将它们都放在左边......永远。
只需将比较更改为
if (list.IndexOf(item) < (list.Count / 2))
此外,您不应使用 IndexOf
,因为如果您在列表中有重复项,它将 return 第一项而不是当前项的索引。因此,其中两次包含 "abc" 的列表将 return 0 两次,您将陷入同一个无限循环。相反,您可以像这样 for
循环
for (int i = 0; i < list.Count; i++)
{
if (i < (list.Count / 2))
{
left.Add(list[i]);
}
else
{
right.Add(list[i]);
}
}