以下合并k链表的TimeComplexity

时间:2016-07-15 20:42:25

标签: c merge linked-list time-complexity

http://www.geeksforgeeks.org/merge-k-sorted-linked-lists/

参考链接: 分解和征服战略如何给出O(nk Log k)复杂性请解释。 另外,我用不同的方式编写了相同的代码。唯一的区别在于合并模式。我合并了前两个链接结果,然后将其结果与另一个链接列表合并。

这会有什么复杂性?

Node * mergek(){
    int n;
    puts("Enter number of linked list you want to enter");
    scanf("%d",&n);
    Node ** arr=malloc(sizeof(Node *)*n);
    int i=0;
    for(i=0;i<n;i++){
        arr[i] = takeInput();
    }
    for(i=0;i<n;i++){
        print(arr[i]);
    }
    Node * temp=NULL;
    for(i=0;i<n;i++){
        if(i==0){
            temp=merge(arr[i],arr[i+1]);
            i=i+1;
        }   
        else{
            temp=merge(arr[i],temp);
        }   
    }
    return temp;    
}

我想知道这是否具有相同的复杂性或不相同。 O(nklog(k))复杂性。

合并的数量保持不变。

1 个答案:

答案 0 :(得分:0)

虽然合并的数量保持不变,但合并的模式实际上使时间复杂性变得更糟。假设您在merge()时间内O(n + m)函数merge two sorted linked lists(其中n =第一个列表的大小,m =第二个大小)和O(1)空格,请考虑以下分析其中我假设每个列表平均有n个元素。

  • 首次合并将为O(n + n),因为我们正在合并两个n大小的列表
  • 第二次合并将为O(2n + n),因为我们正在将一个n大小的列表与我们现在的2n大小的列表合并
  • 第三次合并将是O(3n + n) ......依此类推。

此时我们必须将Big-Oh中的所有添加内容添加到:

O(2n + 3n + 4n + 5n + ... + kn)

所有这些n字词的总和基本上是n*(k(k+1))/2,因为(k(k+1))/2是第一个k数字的总和。通过从(k(k+1))/2中取常数因子和低阶项,我们可以看到O((k(k+1))/2) = O(k^2),从而使算法O(n*k^2)具有时间复杂度。

我写了一篇关于这个问题的小文章并进一步分析了复杂性差异的程度。你应该看看 here

要回答关于分而治之的方法如何实际产生O(nk * log(k))的另一个问题,请考虑合并排序的工作原理。

如果我们有$ n $项,则合并排序会n工作量,在成为一个完整列表之前将成对合并n项所需的次数。这个数字是log(n)(n的对数基数为2),因此它需要与nlog(n)成比例的步骤(再次,意识到我们正在进行n工作,因为总有游戏中n个元素,log(n)次)。合并排序必须在合并它们之前将列表分解为单个元素的原因是因为单个单元是我们可以获得的最小的东西,根据定义,排序,没有我们做任何排序工作。

在我们的例子中,每个列表都已经排序,因此我们可以将每个k列表(大小为~n)视为按定义排序的元素。无需进一步打破已排序的列表。由于k个列表中每个都有n个元素,因此总会有n*k个元素在起作用。幸运的是,由于每个列表已经排序,我们只需将k“元素”合并在一起,而不是所有n*k列表元素。因此,相同的逻辑占主导地位,因为我们必须将k个元素/列表合并在一起。由于每个列表需要O(n)次合并,而O(1)处理n*k个别元素时,需要时间与O(nk*log(k))成比例。