我正在学习编码,虽然我尝试编写合并排序算法(我们在分析课程中听到的但不是家庭作业)。我正在使用培训师向我们展示的伪代码,但我无法确定问题。有人有机会指出我正确的方向吗?
编辑:算法仅返回List中的第一个值。
static List<int> mergeSort(List<int> mj)
{
List<int>m = mj;
if(m.Count <= 1)
return m;
List<int> merge = new List<int>();
List<int> left = new List<int>();
List<int> right = new List<int>();
int middle = m.Count/2;
for (int i = 0; i < middle; i++)
left.Add(m[i]);
for (int j = middle; j >= m.Count; j++)
right.Add(m[j]);
left = mergeSort(left);
right = mergeSort(right);
merge.AddRange(left);
merge.AddRange(right);
for (int k = 0; k < merge.Count; k++)
{
Console.Write(merge[k] + ",");
}
return merge;
}
答案 0 :(得分:6)
你的代码问题(除了Mike Cowan提到的错误)是你没有进行任何实际的排序。你首先递归地将你的列表分成两半(这是正确的),但是你只是简单地将它们按原始顺序连接在一起,从而没有结果:
merge.AddRange(left);
merge.AddRange(right);
您需要做的是迭代您的两个子列表(通过归纳,应该分别在递归调用中排序),并按顺序将元素添加到合并列表 。
我们首先将0 th 元素:left[0]
与right[0]
进行比较。无论哪个较小,都会添加到merge
列表中,并且其子列表的计数器会递增。假设left[0] < right[0]
:我们将left[0]
添加到merge
,然后在下一次迭代中,我们需要针对left[1]
考虑right[0]
。如果left[1]
再次缩小,我们会将其添加到merge
,然后在下一次迭代中,将left[2]
与right[0]
进行对比。如果right[0]
现在是两者中的较小者,我们会将 it 添加到merge
,并在下一次迭代中将left[2]
与right[1]
进行比较。等等。
这一直持续到其中一个子列表用完为止。当发生这种情况时,我们只需将剩余子列表中的所有元素添加到merge
。
int leftIndex = 0;
int rightIndex = 0;
while (leftIndex < left.Count && rightIndex < right.Count)
if (left[leftIndex] < right[rightIndex])
merge.Add(left[leftIndex++]);
else
merge.Add(right[rightIndex++]);
while (leftIndex < left.Count)
merge.Add(left[leftIndex++]);
while (rightIndex < right.Count)
merge.Add(right[rightIndex++]);
此外,您不应该在的递归方法中写入控制台。将Console.Write
来电转移到Main
方法:
static void Main(string[] args)
{
List<int> original = new List<int>(new int[] { 4, 75, 12, 65, 2, 71, 56, 33, 78,1, 4, 56, 85, 12, 5,77, 32, 5 });
List<int> sorted = mergeSort(original);
for (int k = 0; k < sorted.Count; k++)
Console.Write(sorted[k] + ",");
}
答案 1 :(得分:5)
这一行:
for (int j = middle; j >= m.Count; j++)
right.Add(m[j]);
应为:
for (int j = middle; j < m.Count; j++)
right.Add(m[j]);
答案 2 :(得分:4)
首先,该行
for (int j = middle; j >= m.Count; j++)
应该是
for (int j = middle; j < m.Count; j++)
另外,你实际上从未实际合并左右,你只是将它们放在彼此的顶部。这条线
merge.AddRange(left);
merge.AddRange(right);
应该像
mergeLeftRight(left, right)
其中 mergeLeftRight 是您定义的第二个执行实际排序的函数。阅读关于合并排序的维基百科文章:http://en.wikipedia.org/wiki/Merge_sort
答案 3 :(得分:2)
简单的合并排序步骤