C# 排序数字数组问题
昨天上班时,我开始研究如何在不使用库方法Array.sort的情况下对数字进行排序。在时间允许的情况下,我时断时续地工作,终于在今天结束时想出了一个基本的工作算法。这可能是相当愚蠢和最慢的方式,但我满足于我有一个工作代码 但是,逻辑中存在错误或缺失,导致输出在打印行之前挂起:C# 排序数字数组问题,c#,sorting,C#,Sorting,昨天上班时,我开始研究如何在不使用库方法Array.sort的情况下对数字进行排序。在时间允许的情况下,我时断时续地工作,终于在今天结束时想出了一个基本的工作算法。这可能是相当愚蠢和最慢的方式,但我满足于我有一个工作代码 但是,逻辑中存在错误或缺失,导致输出在打印行之前挂起:已排序的数字。(2011年12月17日凌晨2:11:42) 此延迟与阵列中的元素数成正比。具体来说,输出挂起在我在下面的结果部分中放置波浪线的位置在明显延迟之后,将打印瓷砖后面的内容。 以下是进行排序的代码: while(p
已排序的数字。(2011年12月17日凌晨2:11:42)
此延迟与阵列中的元素数成正比。具体来说,输出挂起在我在下面的结果部分中放置波浪线的位置在明显延迟之后,将打印瓷砖后面的内容。
以下是进行排序的代码:
while(pass != unsortedNumLen)
{
for(int i=0,j=1; i < unsortedNumLen-1 && j < unsortedNumLen; i++,j++)
{
if (unsorted[i] > unsorted[j])
{
pass = 0;
swaps++;
Console.Write("Swapping {0} and {1}:\t", unsorted[i], unsorted[j]);
tmp = unsorted[i];
unsorted[i] = unsorted[j];
unsorted[j] = tmp;
printArray(unsorted);
}
else pass++;
}
}
你能帮我找出问题所在吗
这不是家庭作业,只是我在锻炼。将您的while中的条件更改为:
while (pass < unsortedNumLen)
while(通过
从逻辑上讲,pass
从不等于unsortedNumLen
,因此您的while
不会终止
pass
最终等于unsortedNumLen
当它超过int
的最大值并循环到该值时
要查看处于挂起状态时发生的情况,只需在Visual Studio中单击暂停按钮,然后将鼠标悬停在pass
上,即可查看它是否包含巨大的值
您还可以在
while
行上设置断点,并为pass
添加一个手表。这将向您显示列表第一次排序时,pass
等于5。听起来您需要一个提示来帮助您完成排序和学习,因此我不会发布完整的解决方案
将您的else
块更改到下面,看看它是否将您置于正确的轨道上
else {
Console.WriteLine("Nothing to do for {0} and {1}", unsorted[i], unsorted[j]);
pass++;
}
这只是用于排序的算法的一个特征。一旦完成对元素的排序,它就无法知道排序是否完成,因此它会再次对每个元素执行最后一次通过检查。您可以通过添加
--unsortedNumLen代码>位于for循环的末尾,如下所示:
for(int i=0,j=1; i < unsortedNumLen-1 && j < unsortedNumLen; i++,j++)
{
/// existing sorting code
}
--unsortedNumLen;
for(int i=0,j=1;i
原因?由于算法将最大值冒泡到数组末尾,因此无需再次检查此元素,因为已确定它比所有其他元素都大。以下是修复方法:
while(pass < unsortedNumLen)
while(通过
这就是延迟发生的原因
在数组最终排序的for
循环结束后,pass
最多包含unsortedNumLen-2
(如果最后一次更改在第一个和第二个成员之间)。但是它不等于未排序的数组长度,因此while
和for
的内部的另一次迭代开始。由于数组已排序unsorted[i]>unsorted[j]
始终为false,因此pass始终递增-正好是j
递增的次数,即unsortedNumLen-1
。这不等于未排序的numlen
,因此的另一次迭代将在时开始。没有实质性的改变,在这个迭代之后,pass
包含2*(unsortedNumLen-1)
,它仍然不等于unsortedNumLen
。等等
当pass达到值int.MaxValue
时,会发生溢出,变量pass
将获得的下一个值是int.MinValue
。该过程继续进行,直到检查while
条件时,pass
最终获得值unsortedNumLen
。如果你特别不走运,这可能永远不会发生
另外,您可能想看看这个。只是好奇,为什么不使用Array.Sort()
?或者LINQOrderBy()
?您已经“发现”了冒泡排序。还有更好的方法:@JamesMichaelHare:我知道Array.Sort()
和LINQ OrderBy()
。我试着这样做是为了锻炼我的头脑。没什么大不了的。我不会在任何严肃的项目中使用它。@dlev:我明白了。我模模糊糊地记得大学时代的一个算法,并试图实现它。感谢您让我知道它是哪种类型的。我的意思是,如果您有一个程序,并且您正在使用Console.Write()
打印中间状态,那么Console.Out
将被缓冲。因此,当您调用Write()
时,它会将数据放入缓冲区。一旦缓冲区已满,或者调用了对控制台.Read()
等的调用,它就会将该缓冲区刷新到屏幕上。因此,如果您有如下内容:Operations();控制台。写入(“1”);操作();控制台。写入(“2”);操作();控制台。写入(“3”)
和Operations()
需要很长时间,您可能会看到一个很长的“挂起”,然后在末尾弹出1、2、3。编辑:我的错,我误解了你的答案(可能是投票人也误解了)。无论如何,我认为你的答案可以说得更清楚(因为显然,pass
在某一点上的值是正确的),但总的来说,它是正确的。考虑将“从不”改为“需要很长时间”,因为整个点是“代码> PASS <代码>将不断地缠绕直到你走运,它最终出现在<代码>未排序的NUMLLIN < /COD>。@ LoudStVisto,在每次执行for循环时,它肯定不会被设置为零。如果数字已按顺序排列,则不会执行If块,只执行else块。@Dennis我在LINQPad中执行了它,投票给了你,并添加了我自己的答案作为“教人钓鱼”的备选方案。pass
supersedwhile(pass < unsortedNumLen)