这段代码的空间复杂性是什么?

时间:2017-05-01 10:01:33

标签: python sorting

我不确定这两种选择排序实现的空间复杂性:

def selection_sort(lst):
    n = len(lst)
    for i in range(n):
        m_index = i 
        for j in range(i+1,n):
            if lst[m_index] > lst[j]:
                m_index = j
            swap(lst, i, m_index)
    return None

和这一个:

def selection_sort2(lst):
    n = len(lst)
        for i in range(n):
            m = min(lst[i:n])
            m_index = lst.index(m) #find the index of the minimum
            lst[i], lst[m_index] = lst[m_index], lst[i]
    return None

并且,关于第二个代码,一旦m得到一个新切片,保存先前切片的位置在哪里?

谢谢!

1 个答案:

答案 0 :(得分:0)

要说的第一点是你的第二个函数包含使用index的错误。运行这个:

def selection_sort2(lst):
    n = len(lst)
    for i in range(n):
        m = min(lst[i:n])
        m_index = lst.index(m) #find the index of the minimum
        lst[i], lst[m_index] = lst[m_index], lst[i]
    return

l = [5,4,1,3,4]
selection_sort2(l)
print(l)

打印出来

[1, 3, 5, 4, 4]

这是因为您误解了index功能。它的作用是在提供的列表中找到第一次出现的提供值(此处为m)(此处为lst)。所以你的代码首先要做的是创建一个切片并找到它的min。然后切片超出范围并被垃圾收集。然后在整个列表中找到值(在本例中的错误位置)。

我们可以通过将索引限制为切片来解决这个问题,但请记住这不是好代码,我将在下面解释。

    m_index = lst.index(m,i) #find the index of the minimum

通过此更改,该功能可以正常工作,但它有两个问题。第一个是切片(如您所怀疑的)创建副本,因此代码的内存要求加倍。但第二个问题是,一旦找到最小值,您就会毫无意义地再次遍历切片,以找到找到最小值的位置的索引,因此也会使运行时间加倍。

可以通过用生成器表达式替换切片来修复复制。因此,我们只需一次生成一个值,而不是切片。

然后我们可以通过将其与元组中的值一起使用来安排查找最小值的索引。然后最小化元组同时为我们提供索引。结果代码如下所示:

def selection_sort2(lst):
    n = len(lst)
    for i in range(n):
        m,m_index = min((lst[j],j) for j in range(i,n))
        lst[i], lst[m_index] = lst[m_index], lst[i]
    return

然而,这段代码在功能上或多或少与你的第一个例子相同,可能没有更清楚 - 为什么要改变呢?