【问题标题】:Why is the time complexity of creating a heap array not O(log(n!)) instead of O(nlogn)?为什么创建堆数组的时间复杂度不是 O(log(n!)) 而不是 O(nlogn)?
【发布时间】:2020-01-10 14:23:17
【问题描述】:

通过插入函数“insert(A,n)”在堆中插入新元素需要 O(log n) 时间(其中 n 是数组“A”中的元素数)。插入函数如下:

void insert(int A[], int n)
{
   int temp,i=n;
   cout<<"Enter the element you want to insert";
   cin>>A[n];
   temp=A[n];
   while(i>0 && temp>A[(i-1)/2])
   {
      A[i]=A[(i-1)/2];
      i=(i-1)/2;
   }
   A[i]=temp;
}

插入函数的时间复杂度为 O(log n)。

将数组转换为堆数组的函数如下:

void create_heap()
{
   int A[50]={10,20,30,25,5,6,7};
   //I have not taken input in array A from user for simplicity.
   int i;
   for(i=1;i<7;i++)
   {
      insert(A,i);
   }
}

给定这个函数的时间复杂度是O(nlogn)。

-> 但是插入函数在每次调用中都有最多“i”个元素进行比较。即,每次调用的单次循环运行的时间复杂度为 O(log i)。

-> 所以首先是 log1,然后是 log2,然后是 log3,依此类推,直到 log6。

-> 所以对于数组的 n 个元素,总时间复杂度为 log2 + log3 + log4 +..logn

-> 这将是 log(2x3x4x...xn) = log(n!)

那么为什么时间复杂度不是 O(log(n!)) 而是 O(nlogn) ??

【问题讨论】:

    标签: c++ time-complexity heap heapsort


    【解决方案1】:

    Log(n!) 以 log(n^n) 为界,来自 log 规则其 n*logn

    1*2*3*4*....*n = n!
    n*n*n*n*....*n = n^n
    

    很明显!

    那么当O(logn!) 是一个更严格的界限时,为什么还要使用O(nlogn)?因为nlogn 以 log(n!) 为界,很奇怪,不是吗?

    log(1*2*3*4*....*n) = log(1) + log(2) + ... + log(n) 
    

    让我们扔掉上半场

    log(1*2*3*4*....*n) > log(n/2) + log((n/2) + 1) + log((n/2)+2) + ... + log(n) 
                        > log(n/2) + log(n/2) + ... + log(n/2) 
                        = n/2*log(n/2) = O(nlogn)  
    

    【讨论】:

    • 这是否意味着我的分析没有问题?
    • @Avi 您的分析没有问题。将其写为 O(nlogn) 也是正确的,因为 log(n!) 以 log(n^n) 为界,即 nlogn。
    • @TonyTannous 希望我的编辑让它更清楚一点(并希望它是正确的:))
    猜你喜欢
    • 1970-01-01
    • 2021-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-24
    相关资源
    最近更新 更多