关于算法:C数组排序技巧

C Array sorting tips

1
       a=[1,3,6,7,1,2]

这是对以下数组进行排序的最佳排序技术,如果存在重复项,如何处理它们。这也是最好的分类技术…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 void BubbleSort(int a[], int array_size)
 {
 int i, j, temp;
 for (i = 0; i < (array_size - 1); ++i)
 {
      for (j = 0; j < array_size - 1 - i; ++j )
      {
           if (a[j] > a[j+1])
           {
                temp = a[j+1];
                a[j+1] = a[j];
                a[j] = temp;
           }
      }
 }
 }


在C语言中,您可以使用内置的qsort命令:

1
2
3
4
5
6
7
8
9
10
11
int compare( const void* a, const void* b)
{
     int int_a = * ( (int*) a );
     int int_b = * ( (int*) b );

     if ( int_a == int_b ) return 0;
     else if ( int_a < int_b ) return -1;
     else return 1;
}

qsort( a, 6, sizeof(int), compare )

参见:http://www.cplusplus.com/reference/clibrary/cstdlib/qsort/

要回答问题的第二部分:最佳(基于比较)排序算法是一种运行O(n log(n))比较的排序算法。有几个具有此属性(包括快速排序、合并排序、堆排序等),但要使用哪个属性取决于您的用例。

作为旁注,如果你对你的数据有所了解,你有时可以做得比O(n log(n))更好——参见维基百科关于基数排序的文章。


在您的特定情况下,最快的排序可能是这个答案中描述的排序。它针对6个整数的数组进行了精确优化,并使用了排序网络。它比库qsort快20倍(在x86上测量)。对于固定长度数组的排序,排序网络是最佳的。因为它们是一个固定的指令序列,所以它们甚至可以很容易地由硬件实现。

一般来说,有许多针对特定情况优化的排序算法。诸如堆排序或快速排序之类的通用算法针对项目数组的就地排序进行了优化。它们产生O(n.log(n))的复杂性,n是要排序的项目数。

库函数qsort()的编码非常好,并且在复杂性方面效率很高,但是使用了对用户提供的某些comparizon函数的调用,并且此调用的成本相当高。

为了对大量数据进行排序,算法还必须处理与磁盘之间的数据交换,这是在数据库中实现的一种排序,如果您有这样的需要,最好是将数据放入某些数据库并使用内置排序。


视情况而定

这取决于各种因素。但一般来说,使用分治/二分法的算法在排序问题时会表现良好,因为它们呈现出有趣的平均情况复杂性。

基础

要了解哪种算法最有效,您需要了解算法复杂性和big-o符号的基本知识,以便了解它们在平均情况、最佳情况和最坏情况下的比率。如果需要,还必须注意排序算法的稳定性。

例如,通常一个有效的算法是快速排序。但是,如果您给QuickSort一个完全颠倒的列表,那么它将执行得很糟糕(在这种情况下,简单的选择排序将执行得更好!).shell排序通常也是Quicksort的一个很好的补充,如果您对列表进行预分析。

使用分而治之的方法进行"高级搜索",请查看以下内容:

  • 快速排序
  • 贝壳类
  • 合并排序

对于不太复杂的算法,这些更为严格的算法:

  • 起泡口
  • 选择排序
  • 插入排序

进一步

以上是开始时的常见疑点,但还有无数其他疑点。

正如R.在评论中和Kris在回答中指出的那样,您可能想看看Heapsort,它提供了理论上比快速排序更好的排序复杂性(但在实际情况下通常不会更好)。还有变体和混合算法(如timsort)。


最好的排序技术通常取决于数组的大小。合并排序可以是最好的,因为它根据big-o算法管理更好的空间和时间复杂性(这更适合于大型数组)。


我想做些改变:在C中,可以使用内置的qsort命令:

1
2
3
4
5
6
7
8
9
10
int compare( const void* a, const void* b)
{
   int int_a = * ( (int*) a );
   int int_b = * ( (int*) b );

   // an easy expression for comparing
   return (int_a > int_b) - (int_a < int_b);
}

qsort( a, 6, sizeof(int), compare )