排序而不比较元素

时间:2013-10-09 23:39:43

标签: c# c#-4.0

给定数组5的大小,其中包含五个数字,在不进行比较的情况下将它们从最小到最大排序。(提示,访问时间O(n)

我试图搜索很多,但不知道,怎么做。 O(n),意思是哪个算法/数据结构。我不知道。

2 个答案:

答案 0 :(得分:2)

我想你需要Counting sort,它有线性时间,但占用一些内存并取决于初始数组的最小/最大值

答案 1 :(得分:0)

Counting Sort会为你做这件事,虽然如果我在接受采访时当场我可能会做类似下面的事情,这些事情模糊地相似,因为我永远不会记得这些“经典”算法。我的头!

这里的关键思想是使用每个实际未排序的整数值作为目标数组的索引,该目标数组包含N个元素,其中N是最大值。要排序的值。

我使用一个简单的类来记录它发生的值和次数,这样如果你需要在原始数组中保留多次出现的离散值,就可以从中重建一个实际的数组。

所以你需要做的就是遍历未排序的数组,将每个值放入目标数组中的相应索引中,并且(忽略空元素)您的值已经从最小到最大排序,而没有将它们与一个进行比较另一个。

(我个人不喜欢这样的面试问题,答案是“哦,使用Counting Sort”或者其他什么 - 我希望面试官提出这个问题真的很有兴趣看看你有什么方法解决了一个新问题,无论你是否得到严格正确的答案)

下面的性能是O(n)意味着它以线性时间运行(1个元素占用X个时间量,10个元素占用10倍等)但是如果max元素很大,它可以使用大量内存,不能进行就地排序,只能使用原语,这不是我希望在生产代码中看到的东西:)

void Main()
{
   //create unsorted list of random numbers
    var unsorted = new List<int>();
    Random rand = new Random();
    for(int x=0;x<10;x++)
    {
     unsorted.Add(rand.Next(1,10));
    }
    //create array big enough to hold unsorted.Max() elements
    //note this is indirectly performing a comparison of the elements of the array
    //but not for the sorting, so I guess that is allowable :)
    var sorted = new NumberCount[unsorted.Max()+1];
    //loop the unsorted array 
    for (int index=0;index<unsorted.Count;index++)
    {
   //get the value at the current index and use as an index to the target array
        var value = unsorted[index];
        //if the sorted array contains the value at the current index, just increment the count
        if (sorted[value]!=null && sorted[value].Value!=0)
        {
           sorted[value].Count++;
        }
        else
        {
        //insert the current value in it's index position
         sorted[value]=new NumberCount{Value=value,Count=1};          
        }
    }
    //ignore all elements in sorted that are null because they were not part of the original list of numbers.
    foreach (var r in sorted.Where(r=>r!=null))
    {
       Console.WriteLine("{0}, occurs {1} times",r.Value,r.Count);
    }
}

//just a poco to hold the numbers and the number of times they occurred.
public class NumberCount
{
  public int Value{get;set;}
  public int Count{get;set;}
}