Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 哪种排序算法对大部分排序的数据最有效?_Algorithm_Sorting - Fatal编程技术网

Algorithm 哪种排序算法对大部分排序的数据最有效?

Algorithm 哪种排序算法对大部分排序的数据最有效?,algorithm,sorting,Algorithm,Sorting,哪种排序算法对大部分已排序的数据最有效?基于高度科学的观察方法,我认为插入排序和冒泡排序是很好的选择 插入或shell排序 远离快速排序-对于预排序的数据,快速排序效率非常低。插入排序通过移动尽可能少的值来很好地处理几乎已排序的数据。插入排序是排序输入的最佳情况O(n)。它与大部分排序的输入非常接近(优于快速排序)。插入排序具有以下行为: 对于插槽1..n中的每个元素k,首先检查el[k]>=el[k-1]。如果是,请转到下一个元素。(显然跳过第一个元素。) 如果没有,请在元素1..k-1中使用

哪种排序算法对大部分已排序的数据最有效?

基于高度科学的观察方法,我认为插入排序和冒泡排序是很好的选择

插入或shell排序

远离快速排序-对于预排序的数据,快速排序效率非常低。插入排序通过移动尽可能少的值来很好地处理几乎已排序的数据。

插入排序是排序输入的最佳情况O(n)。它与大部分排序的输入非常接近(优于快速排序)。

插入排序具有以下行为:

  • 对于插槽
    1..n
    中的每个元素
    k
    ,首先检查
    el[k]>=el[k-1]
    。如果是,请转到下一个元素。(显然跳过第一个元素。)
  • 如果没有,请在元素
    1..k-1
    中使用二进制搜索来确定插入位置,然后快速移动元素。(只有当
    k>T
    其中
    T
    是某个阈值时,才可以这样做;如果
    k
    很小,这就太过分了。)

  • 此方法进行的比较次数最少。

    Pound Try Heap。我相信它是O(n lg n)排序中最一致的。

    正如其他人所说的,小心天真的快速排序-在排序或接近排序的数据上可能有O(n^2)性能。尽管如此,使用合适的算法选择轴心点(随机或三个轴心点的中间值),Quicksort仍然可以正常工作

    一般来说,选择诸如插入排序之类的算法的困难在于决定何时数据的顺序足够混乱,这样快速排序会更快。

    尝试内省排序

    它是基于快速排序的,但它避免了快速排序对于几乎排序的列表所具有的最坏情况

    诀窍在于,这种排序算法检测快速排序进入最坏情况模式并切换到堆或合并排序的情况。几乎排序的分区由一些非Naive分区方法检测,小分区则由插入排序处理

    您获得了所有主要排序算法中最好的一种,从而降低了代码和复杂性。您可以确保,无论数据看起来如何,您都不会遇到最坏的情况


    如果你是C++程序员,请检查你的STD::排序算法。它可能已经在内部使用了内省排序。

    我不想在这里假装拥有所有答案,因为我认为获得实际答案可能需要对算法进行编码,并根据代表性数据样本对其进行分析。但我整个晚上都在思考这个问题,下面是我到目前为止所想到的,以及一些关于什么在哪里最有效的猜测

    设N为项目总数,M为无序数

    冒泡排序必须使2*M+1这样的东西通过所有N个项目。如果M很小(0,1,2?),我认为这将很难被击败

    如果M很小(比如小于logn),插入排序将具有很好的平均性能。然而,除非有我看不到的技巧,否则它将有非常糟糕的最坏情况性能。(对吗?如果订单中的最后一项先到,那么就我所知,你必须插入每一项,这将破坏性能。)我猜对于这种情况有一种更可靠的排序算法,但我不知道它是什么

    如果M大于(比如等于或大于logn),则内省排序几乎肯定是最好的

    例外:如果您确实提前知道哪些元素是未排序的,那么您的最佳选择是将这些项目取出,使用内省排序对它们进行排序,然后将两个排序的列表合并到一个排序的列表中。如果你能很快找出哪些项目出了问题,这也是一个很好的通用解决方案——但我还没有找到一个简单的方法来解决这个问题

    进一步思考(隔夜):如果M+1 对这个问题的另一种解释是,可能有许多无序的项目,但它们非常接近它们应该在列表中的位置。(想象一下,从一个排序的列表开始,然后用后面的一个项目交换其他所有项目。)在这种情况下,我认为冒泡排序的性能非常好——我认为通过的次数将与项目的最远位置成正比。插入排序的效果很差,因为每个无序项都会触发插入。我怀疑内省排序或类似的方法也能很好地工作。

    是一种基于自适应二叉树的模糊排序方法。Splaysort不仅适用于部分排序的数据,还适用于部分反向排序的数据,或者任何具有任何类型的预先存在的顺序的数据。在一般情况下为O(nlogn),在数据以某种方式排序的情况下为O(n)(正向、反向、风琴管等)

    与插入排序相比,它的最大优势在于,当数据根本没有排序时,它不会恢复为O(n^2)行为,因此在使用它之前,不需要绝对确保数据已部分排序

    它的缺点是所需的splay树结构的额外空间开销,以及构建和销毁splay树所需的时间。但是,根据数据的大小和您预期的预分类量,对于速度的提高,开销可能是值得的

    一篇文章发表在《软件实践》上