繁体   English   中英

分析shell排序算法(大O)

[英]Analyzing shell sort algorithm (big O)

这就是shell排序算法。

  void shellSort(int array[], int n){
    for (int gap = n/2; gap > 0; gap /= 2){
        for (int i = gap; i < n; i += 1) {
           int temp = array[i];
           int j;

           for (j = i; j >= gap && array[j - gap] > temp; j -= gap){
              array[j] = array[j - gap];
           }
           array[j] = temp;
        }
      }
  }

我确定该算法的外循环运行logn次,但我不确定中间循环和最内循环。 这个站点https://stackabuse.com/shell-sort-in-java/说中间循环运行n-gap次,而最内层循环运行i/gap但我不太确定。 请帮助我理解中间和最内层循环如何在这个算法中运行,非常感谢任何帮助我的人。

这些是算法中的循环:

for (int gap = n/2; gap > 0; gap /= 2) {
  for (int i = gap; i < n; i += 1) {
    for (j = i; j >= gap && array[j - gap] > temp; j -= gap) {
    }
  }
}

让我们从循环i开始。 它从gap开始并以n为增量进入n 。下一个j循环从当前i开始并向下走gap直到它变得小于gap 因此,遍历j执行一次用于i之间gap2*gap ,两次, i之间2*gap3*gap ,三个时间为i之间3*gap4*gap等。

这意味着, j循环将用于执行一次gap的不同值i ,两次gap的不同值i ,三次gap的不同值i

i的最大值是n ,因此j的循环可以执行最大j_max = (n - gap)/gap次数。 j循环的总执行次数为

1+1+...+1+1 + 2+2+...+2+2 + 3+3+...+3+3 + .... + j_max+j_max+...+j_max+j_max
|_________|   |_________|   |_________|          |_________________________|
 gap times     gap times     gap times                    gap times 

这个总和等于

gap*(sum from 1 to j_max) = gap * j_max(j_max + 1) / 2 = O(gap * ((n-gap)/gap)^2) = O((n-gap)^2/gap)

这将在外循环中针对不同的gap值重复进行,因此复杂度为 O 大

sum((n-gap)^2/gap, for gap = n/2, n/4, n/8, ...., 4, 2, 1)

扩展:

(n^2 - 2*n*gap + gap^2)/gap = n^2*(1/gap) - 2*n + gap

第一项等于n平方乘以以下值:

1/(n/2),  1/(n/4),  1/(n/8), ..... 1/4,  1/2, 1/1

或者

2/n, 4/n, 8/n, ....., n/n

这是 2 的幂除以n的总和,所以第一项总共给出

n^2/n * 2^(log2 n) = n^2

第二项是-2*n log2 n次相加,所以复杂度是

n*log2 n

最后一项是gaps之和,因此它是 2 的幂之和,其复杂度为n 将所有组合在一起,我们得到最坏情况的复杂度为 O(n^2)。

在每次迭代中,中间循环从 gap 开始,在 n 结束。 所以总迭代次数将是n - gap

内部间隙从 i 开始。 在每次迭代中,它都会减少间隙。 假设 i = 15 且间隙 = 3,则后续迭代中 j 的值将为 15、12、9、6、3。 这是5次迭代。 因此在最坏的情况下i/gap迭代。

求等差数列项数的公式是(最后一项-第一项)/差+1

for (int i = gap; i < n; i += 1)从 i = gap 开始,当 i == n 时退出。 我可以取的最后一个值是 n - 1。

每个循环,i 增加 1,所以这个循环被执行 (n - 1 - gap) / 1 + 1 = n - gap 时间

for (j = i; j >= gap && array[j - gap] > temp; j -= gap)

这个循环从 j = 1 开始,当 j < gap 时退出(假设最坏情况,忽略第二部分)。 j 可以采用的最后一个值是间隙。

每个循环,j 递减gap,所以这个循环被执行 (i - gap)/gap + 1 = i

暂无
暂无

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

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