如何找到递归选择排序的时间复杂度?

时间:2017-10-15 16:51:48

标签: c++ algorithm recursion data-structures

嘿伙计我有一个测验tommorow我面临一些问题找到时间复杂的递归程序的选择排序可以任何人解释它是如何n ^ 2。还有一个问题,一些排序算法循环有n / 2时间复杂度/ 2抱歉新手问题的含义。

#include <iostream>
using namespace std;

// recursive function to perform selection sort on subarray arr[i..n-1]
void selectionSort(int arr[], int i, int n)
{
    // find the minimum element in the unsorted subarray[i..n-1]
    // and swap it with arr[i]
    int min = i;
    for (int j = i + 1; j < n; j++)
    {
        // if arr[j] element is less, then it is the new minimum
        if (arr[j] < arr[min])
            min = j;    // update index of min element
    }

    // swap the minimum element in subarray[i..n-1] with arr[i]
    swap(arr[min], arr[i]);

    if (i + 1 < n)
        selectionSort(arr, i + 1, n);
}

1 个答案:

答案 0 :(得分:2)

寻找时间复杂度通常以一种不太有用的方式描述。以下是选择排序的工作原理。

<强>通过
第一次通过算法时,您必须扫描数据的所有 n 元素。

下一次(在递归时),您必须扫描除一个之外的所有内容,即( n -1)。

等等。我们可以将我们查看/比较元素的次数写为:

n + (n-1) + (n-2) + ... + 2 + 1

(你可以对最后一个词进行狡辩,但为了简单起见,我们不会在乎。你会在一秒钟内看到原因。)

数学身份
这个特殊的系列(注意所有的添加)被称为“算术级数”。每个术语之间的差异为1.第一个术语是 n ,最后一个术语是1(或2,无论如何)。

使用一些数学,大多数人在高中时都不记得(或没有教过),我们可以将这笔钱重写为:

n(n+1)
──────
  2

(是的,再说一遍,上一个词实际上应该是两个,即使我把它留在了一个。)

随着 n 增长任意大
Big O并不关心 n 的友好价值。它关心当 n 变得任意大时会发生什么。我们说“ n 向无限增长”。

正如它所做的那样,我们可以注意到两件事情发生了:

  • 除以2的除法变得无关紧要:∞/ 2→∞
  • 加1(或其他)也是无关紧要的:∞(∞+ 1)→∞(∞)

所以最终,我们有无穷大,呃, n 乘以它自己。该等式简化为:

n(n+1)
──────  →  n²
  2

复杂性界限
最坏的情况是n²,所以我们注释为“O(n²)”。但请注意,最佳情况也是n²。我们注释为“Ω(n²)”。最后,由于最佳和最差情况行为是相同的,我们对函数的行为有一个非常好的紧束缚。我们将其注释为“Θ(n²)”。

因此,选择排序具有Θ(n²)复杂度。

圣洁的quiznak!我应该这样做我自己!!
是的,不幸的是,弄清楚复杂性是人们对待的事情之一,就好像它真的很容易 - 即使他们自己也不了解它。它需要熟悉数学和一些练习。典型的反应与上面提供的链接一样:“查看这些常见情况并选择最匹配的情况”。我个人觉得这不那么令人满意。这也是大学教授希望你立即接受的事情之一。

我的建议:不要太担心。尽力了解基本原则。我们正在做的是找到一个函数(比如y =x²),它表示算法在其输入非常大(n→∞)时的行为。

能够跟踪算法所采用的路径并识别这些路径何时昂贵是比能够提出数学家答案更重要的能力。如果你真的需要它,你总能找到一位数学家来帮助你,无论是在大学还是在互联网上,如果你在合适的地方提出要求。

当然,随时可以花时间尝试更好地理解和练习。无论其他人是否看到它,能够做到正确是一项宝贵的技能。

:O)