简体   繁体   English

排序数字数组问题

[英]Sorting numbers array issue

Yesterday at work I set out to figure out how to sort numbers without using the library method Array.Sort . 昨天在工作中我开始计算如何在不使用库方法Array.Sort情况下对数字进行排序。 I worked on and off when time permitted and finally was able to come up with a basic working algorithm at the end of today. 我在时间允许的情况下上班和下班,最后能够在今天结束时提出基本的工作算法。 It might be rather stupid and the slowest way, but I am content that I have a working code. 它可能是相当愚蠢和最慢的方式,但我满足于我有一个工作代码。

But there is something wrong or missing in the logic, that is causing the output to hang before printing the line: Numbers Sorted. (12/17/2011 2:11:42 AM) 但是逻辑中存在错误或缺失,导致输出在打印行之前挂起: Numbers Sorted. (12/17/2011 2:11:42 AM) Numbers Sorted. (12/17/2011 2:11:42 AM)

This delay is directly proportionate to the number of elements in the array. 此延迟与阵列中元素的数量成正比。 To be specific, the output just hangs at the position where I put the tilde in the results section below. 具体来说,输出只是挂在我将波浪号放在下面结果部分的位置。 The content after tilde is getting printed after that noticeable delay. 在明显延迟之后打印波尔德之后的内容。

Here is the code that does the sort: 以下是执行排序的代码:

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++;
    }
}

The results: 结果:

Numbers unsorted. (12/17/2011 2:11:19 AM)

4 3 2 1
Swapping 4 and 3:       3 4 2 1
Swapping 4 and 2:       3 2 4 1
Swapping 4 and 1:       3 2 1 4
Swapping 3 and 2:       2 3 1 4
Swapping 3 and 1:       2 1 3 4
Swapping 2 and 1:       1 2 3 4
~
Numbers sorted. (12/17/2011 2:11:42 AM)

1 2 3 4
Number of swaps: 6

Can you help identify the issue with my attempt? 我可以帮助您确定尝试的问题吗?

Link to full code 链接到完整代码
This is not homework, just me working out. 这不是功课,只是我锻炼。

Change the condition in your while to this: 将你的情况改为:

while (pass < unsortedNumLen)

Logically pass never equals unsortedNumLen so your while won't terminate. 逻辑上pass 永远不等于unsortedNumLen所以你的while不会终止。

pass does eventually equal unsortedNumLen when it goes over the max value of an int and loops around to it. pass超过int的最大值并循环到它时, pass最终会等于unsortedNumLen

In order to see what's happening yourself while it's in the hung state, just hit the pause button in Visual Studio and hover your mouse over pass to see that it contains a huge value. 为了查看处于挂起状态时自己发生了什么,只需点击Visual Studio中的暂停按钮,将鼠标悬停在pass即可看到它包含巨大的值。

You could also set a breakpoint on the while line and add a watch for pass . 您还可以在while行上设置断点并添加一个pass for pass That would show you that the first time the list is sorted, pass equals 5. 这将向您显示列表第一次排序时, pass等于5。

It sounds like you want a hint to help you work through it and learn, so I am not posting a complete solution. 听起来你想要一个提示来帮助你完成它并学习,所以我没有发布一个完整的解决方案。

Change your else block to the below and see if it puts you on the right track. 将您的else块更改为以下内容,看看它是否能让您走上正确的轨道。

else {

    Console.WriteLine("Nothing to do for {0} and {1}", unsorted[i], unsorted[j]);
    pass++;
}

Here is the fix: 这是修复:

while(pass < unsortedNumLen)

And here is why the delay occurred. 这就是延迟发生的原因。

After the end of the for loop in which the array was eventually sorted, pass contains at most unsortedNumLen - 2 (if the last change was between first and second members). 在最终对数组进行排序的for循环结束之后, pass最多包含unsortedNumLen - 2 (如果最后一次更改是在第一个和第二个成员之间)。 But it does not equal the unsorted array length, so another iteration of while and inner for starts. 但它不等于unsorted数组长度,所以另一次迭代while和内for启动。 Since the array is sorted unsorted[i] > unsorted[j] is always false, so pass always gets incremented - exactly the number of times j got incremented, and that is the unsortedNumLen - 1 . 由于数组unsorted[i] > unsorted[j]始终为false,因此pass总是递增 - 正好是j递增的次数,即unsortedNumLen - 1 Which is not equal to unsortedNumLen , and so another iteration of while begins. 这不等于unsortedNumLen ,因此while另一次迭代开始。 Nothing essentially changed, and after this iteration pass contains 2 * (unsortedNumLen - 1) , which is still not equal to unsortedNumLen . 没有什么实质上改变,并且在此迭代之后pass包含2 * (unsortedNumLen - 1) ,它仍然不等于unsortedNumLen And so on. 等等。

When pass reaches value int.MaxValue , it the overflow happens, and next value the variable pass will get is int.MinValue . 当pass到达int.MaxValueint.MaxValue ,溢出发生,而pass得到的变量pass下一个值是int.MinValue And the process goes on, until pass finally gets the value unsortedNumLen at the moment the while condition is checked. 并且过程继续进行,直到pass最终在检查while条件时获得值unsortedNumLen If you are particularly unlucky, this might never happen at all. 如果你特别不走运,这可能永远不会发生。

PS You might want to check out this link . PS您可能想查看此链接

This is just a characteristic of the algorithm you're using to sort. 这只是您用于排序的算法的一个特征。 Once it's completed sorting the elements it has no way of knowing the sort is complete, so it does one final pass checking every element again. 一旦完成对元素的排序,它就无法知道排序是否完整,因此它会再次检查每个元素。 You can fix this by adding --unsortedNumLen; 您可以通过添加--unsortedNumLen;来解决此--unsortedNumLen; at the end of your for loop as follows: 在你的for循环结束时如下:

for(int i=0,j=1; i < unsortedNumLen-1 && j < unsortedNumLen; i++,j++)
{
/// existing sorting code
}
--unsortedNumLen;

Reason? 原因? Because you algorithm is bubbling the biggest value to the end of the array, there is no need to check this element again since it's already been determined to be larger the all other elements. 因为您的算法将最大值冒泡到数组的末尾,所以不需要再次检查此元素,因为已经确定它比所有其他元素更大。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM