回归n log(n)排序

时间:2013-04-03 03:28:04

标签: performance algorithm sorting

我有一个排序算法,需要执行n log n排序n次,每步减少1次?换句话说:我希望表现为O(n log n + (n-1) log (n-1) + (n-2) log (n - 2) + ... )。这个问题绝对不会让我感觉像以前没有遇到的事情所以我必须要问:

n log n排序n次的数量级性能是多少,每一步n减1;

4 个答案:

答案 0 :(得分:2)

N ^ 2 log(N)

你正在做N次NlogN操作N次,所以N次NlogN是解决方案。

哦,你的编辑后,它是完全不同的。很难弄清楚总和,但它的上限(这是大O都是)仍然是N ^ 2 log(N)。你或许可以找出更接近的上限,但我认为这是一个可行的解决方案。

有关更精确的解决方案,请参阅https://math.stackexchange.com/questions/135787/asymptotic-formula-for-the-logarithm-of-the-hyperfactorial

更精确的解决方案仍然高于N ^ 2 logN(相当多),所以我认为它仍然是一个安全的上限。

答案 1 :(得分:1)

约为0.5 * n 2 * log(n):

#include <stdio.h>
#include <math.h>

#define MAX 100
double sum[1 + MAX];

int main(void)
{
  int i;

  sum[0] = 0;

  for (i = 1; i <= MAX; i++)
  {
    sum[i] = sum[i - 1] + i * ceil(log2(i));
    printf("%i %.0f %.0f\n", i, sum[i], ceil(log2(i) * i * i / 2));
  }

  return 0;
}

输出(ideone):

1 0 0
2 2 2
3 8 8
4 16 16
5 31 30
6 49 47
7 70 69
8 94 96
9 130 129
10 170 167
...
90 25871 26293
91 26508 26946
92 27152 27608
93 27803 28279
94 28461 28959
95 29126 29647
96 29798 30344
97 30477 31050
98 31163 31764
99 31856 32488
100 32556 33220

答案 2 :(得分:1)

Time = SUM { k log k } for k: 1..n = log(H(n)) ~ Θ(log(H(n)))

H(n):n

中的超因式函数

渐近逼近:

我将尝试通过推广k来推导f(n)作为上界的近似值。

f(n) = log n * SUM { k } for k: 1..n

f(n) = log n * 1/2 n (n+1)

f(n) = 1/2 n log n (n+1)

O(f(n)) = O(1/2 n^2 log n (n+1))

~ O(n^2 log n)

我将尝试通过推广log(k)来推导出g(n)作为下界的近似值。

g(n) = n * SUM { log(k) } for k: 1..n

g(n) = n * log(1/2 n(n+1))

g(n) = n * (log(1/2) + log(n) + log(n+1))

g(n) = n * (c + log(n) + log(n+1))

g(n) = n * (c + log(n(n+1)))

Ω(g(n)) = Ω(n * (c + log(n^2+n))) = Ω(n * log(n^2+n))

~ Ω(n log(n^2+n))

所以,我们有:

Ω(n log(n^2+n)) < Θ(log(H(n))) < O(n^2 log n)

示例:

n = 100; Ω(922.02) < Θ(20,756.7) < O(46,051.7)

n = 1000; Ω(1.38 × 10^4) < Θ(3.2 × 10^6) < O(6.9 × 10^6)

注意:f(n)和g(n)是边界的渐近逼近,它们不准确..

答案 3 :(得分:0)

这是Theta(N^2 log N)

显然是O(N^2 log N)

要显示它是Omega(N^2 log N),请仅考虑序列的大半部分,其中k的每个值至少为N/2。为简单起见,假设N是偶数。

Sum[k=1..N](k log k) >= Sum[k=N/2..N](k log k)           ; drop the small half
                     >= Sum[k=N/2..N]((N/2) log (N/2))   ; since each k >= N/2
                     >= N/2 * N/2 * log (N/2)
                      = N^2/4 * (log N - log 2)
                      = N^2/4 * logN - c
                      ∈ Omega(N^2 log N)