简体   繁体   English

O(n ^ 2)或O(n log n)?

[英]O(n^2) or O(n log n)?

Algorithm 算法

Basically, is the below algorithm O(n log n) or O(n^2). 基本上是下面的算法O(n log n)或O(n ^ 2)。 I'm sure the algorithm has a name; 我确定算法有一个名字; but I'm not sure what it is. 但我不确定是什么。

pseudo-code: 伪代码:

def sort(list):
    dest = new list
    for each element in list (call it a):
        for each element in dest (call it c):
            if a <= c, insert a into dest directly before c
    return dest

in Java: 在Java中:

public static List<Integer> destSort(List<Integer> list) {
    List<Integer> dest = new ArrayList<>();
    for (Integer a : list) {
        if (dest.isEmpty()) {
            dest.add(a);
        } else {
            boolean added = false;
            for (int j = 0; j < dest.size(); j++) {
                int b = dest.get(j);
                if (a <= b) {
                    dest.add(j, a);
                    added = true;
                    break;
                }
            }
            if(!added) {
                dest.add(a);
            }
        }
    }
    return dest;
}

Simply speaking, this algorithm walks a list, and inserts each element into a newly created list in its correct location. 简而言之,该算法遍历一个列表,并将每个元素插入其正确位置的新创建的列表中。

Complexity 复杂

This is how I think about the complexity of this algorithm: 这就是我对这种算法的复杂性的看法:

  • For each element in the list, dest increases in size by 1 对于列表中的每个元素,dest的大小增加1
  • This means that, at each step, the algorithm has a worst-case time of the size of dest 这意味着,在每个步骤中,算法的最坏情况时间为dest大小
  • Summing those up, we'd get 0 + 1 + 2 + 3 + ... + n 总结一下,我们将得到0 + 1 + 2 + 3 + ... + n
  • The sum of all natural numbers up to n = n(n+1)/2 所有自然数之和,直到n = n(n+1)/2
  • This simplifies to (n^2 - n)/2 , and by removing constant & low degree terms, we get O(n^2) 这简化为(n^2 - n)/2 ,并且通过删除常数项和低度项,我们得到O(n ^ 2)

Therefore the complexity is O(n^2). 因此,复杂度为O(n ^ 2)。

However, I was recently browsing this answer , in which the author states: 但是,我最近正在浏览此答案 ,作者在其中指出:

O(n log n): There was a mix-up at the printer's office, and our phone book had all its pages inserted in a random order. O(n log n):打印机办公室里有些混乱,我们的电话簿中所有页面都以随机顺序插入。 Fix the ordering so that it's correct by looking at the first name on each page and then putting that page in the appropriate spot in a new, empty phone book. 通过查看每个页面上的名字,然后将该页面放在新的空电话簿中的适当位置,可以更正顺序,使其正确无误。

This, to me, sounds like the same algorithm, so my question is: 对我来说,这听起来像是相同的算法,所以我的问题是:

  • Is the algorithm I described the same as the one described by @John Feminella? 我描述的算法与@John Feminella描述的算法相同吗?
  • If it is, why is my calculation of O(n^2) incorrect? 如果是,为什么我对O(n ^ 2)的计算不正确?
  • If it isn't, how do they differ? 如果不是,它们有何不同?

The algorithm you have described is different than the O(n log n) algorithm described in the linked answer. 您描述的算法与链接答案中描述的O(n log n)算法不同。 Your algorithm is, in fact, O(n^2). 实际上,您的算法是O(n ^ 2)。

The key difference is in the way the correct location for each element is determined. 关键区别在于确定每个元素的正确位置的方式。 In you algorithm, each element is searched in order, meaning that you check every element against every other already-sorted element. 在您的算法中,将按顺序搜索每个元素,这意味着您将对每个元素与其他已排序元素进行检查。 The linked algorithm is predicated on the O(log n) method used for finding a person's name: 链接算法基于O(log n)方法来查找人的名字:

O(log n): Given a person's name, find the phone number by picking a random point about halfway through the part of the book you haven't searched yet, then checking to see whether the person's name is at that point. O(log n):给定一个人的名字,通过从您尚未搜索的书本的大约一半处随机选择一个点来找到电话号码,然后检查该人的名字是否在该点上。 Then repeat the process about halfway through the part of the book where the person's name lies. 然后在此人名字所在的部分的一半左右重复该过程。 (This is a binary search for a person's name.) (这是对人名的二进制搜索。)

If you use this method to find where each page should go in the new book, you only end up doing O(log n) operations for each page, instead of O(n) operations per page as in your algorithm. 如果使用此方法查找新书中每个页面的位置,则最终只会对每个页面执行O(log n)操作,而不是像算法中那样对每个页面执行O(n)操作。


Incidentally, the algorithm you have described is essentially an insertion sort , although it uses two lists instead of sorting in-place. 顺便说一句,您描述的算法本质上是一个插入排序 ,尽管它使用两个列表而不是就地排序。

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

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