插入排序比较?

时间:2015-10-23 20:22:41

标签: algorithm sorting

如何计算插入排序中的比较次数小于O(n ^ 2)?

3 个答案:

答案 0 :(得分:2)

当我们插入一个元素时,我们交替进行比较和交换,直到(1)元素比较右边的元素(2)我们点击数组的开头。在情况(1)中,存在一个未与交换配对的比较。在情况(2)中,每个比较都与交换配对。比较次数的向上调整可以通过计算从左到右的连续最小值的数量(或者你的插入排序有效)来计算,时间为O(n)。

num_comparisons = num_swaps
min_so_far = array[0]
for i in range(1, len(array)):
    if array[i] < min_so_far:
         min_so_far = array[i]
    else:
         num_comparisons += 1

答案 1 :(得分:0)

如评论所述,如果你必须为分拣付出代价,那么在低于O(n ^ 2)的情况下这样做很难,也许是不可能的。如果您已经知道在每次外部迭代中完成的比较次数,则可以在O(n)中进行,但是排序的价格是在之前的某个时间支付的。

这是一种计算方法内部比较的方法(在伪C ++中):

void insertion_sort(int p[], const size_t n, size_t & count)
{
  for (long i = 1, j; i < n; ++i)
    {
      auto tmp = p[i];
      for (j = i - 1; j >= 0 and p[j] > tmp; --j) // insert a gap where put tmp
        p[j + 1] = p[j];

      count += i - j; // i - j is the number of comparisons done in this iteration
      p[j + 1] = tmp;
    }
}

n是比较计数器的元素数量和count,它必须接收一个设置为零的变量。

答案 2 :(得分:0)

如果我没记错的话,这就是插入排序的工作原理:

A = unsorted input array
B := []; //sorted output array
while(A is not empty) {
    remove first element from A and add it to B, preserving B's sorting
}

如果从左侧通过线性搜索实现对B的插入,直到找到更大的元素,那么比较的数量就是(i,j)对的数量i < jA[i] >= A[j](我正在考虑稳定变体)。

换句话说,对于每个元素x,计算x之前具有较小或相等值的元素数。这可以通过从左侧扫描A,将其元素添加到某个平衡二叉搜索树来完成,这也会记住每个节点下的元素数量。在这样的树中,您可以在O(log n)中找到小于或等于某个值的元素数。总时间:O(n log n)