我在Python 2.7中编写了一个递归插入排序函数,遇到了两件我无法理解的事情。
第一个是错误TypeError: can only assign an iterable
,我猜测它与函数的递归有关,但我没有特别注意我的代码的问题:
def recursiveInsertionSort(v):
if len(v)!=2:
v[0:len(v)-1]=recursiveInsertionSort( v[0:len(v)-1])
i=len(v)-1
while v[i-1]>v[i]:
v[i-1], v[i]=v[i], v[i-1]
i-=1
if i==0: return v
它可能连接的第二个问题。
在这种情况下,我甚至没有收到错误(如果你知道为什么请告诉我)但是这个功能没有用。
def recursiveInsertionSort(v):
if len(v)!=2:
recursiveInsertionSort(v[0:len(v)-1])
i=len(v)-1
while v[i-1]>v[i] and i>0:
v[i-1], v[i]=v[i], v[i-1]
i-=1
正如我猜测问题在于函数的递归使用,我纠正了我的错误:
def recursiveInsertionSort(v):
if len(v)!=2:
temp=v[0:len(v)-1]
recursiveInsertionSort( temp)
v[0:len(v)-1]=temp
i=len(v)-1
while v[i-1]>v[i] and i>0:
v[i-1], v[i]=v[i], v[i-1]
i-=1
但我真的想了解这两种行为的原因,你能帮助我吗?
编辑我也问是否有更好的方法:
temp=v[0:len(v)-1]
recursiveInsertionSort( temp)
v[0:len(v)-1]=temp
答案 0 :(得分:0)
第一次实现的问题在于循环内的if
语句。如果由于v[i-1]
小于或等于v[i]
而退出循环,则不会return
任何内容(在Python中与执行return None
相同)。您获得的TypeError
来自递归调用,返回None
值,因为您无法将None
分配给切片。
如果在while
语句中合并这两个条件并在循环结束后无条件地返回v
,则可以使代码的第一个版本有效:
while i > 0 and v[i-1] > v[i]:
v[i-1], v[i] = v[i], v[i-1]
i -= 1
return v
你可能也应该把这个条件放在你的另一个版本中。
至于为什么你的第二个版本不起作用,问题在于你正在切割原始列表,获得一个包含其内容部分副本的新列表。然后你的递归排序正在修改该副本。但是外部函数没有任何方法来查看更改,因为它没有保留对切片副本的引用。您的第三个版本通过明确将切片保存为新变量来解决此问题。
我认为没有更好的方法来完成上一个代码块的确切三行。但是,如果您将函数更改为接受最高索引的可选paraemter进行排序,则可以不进行切片:
def recursiveInsertionSort(v, i=None):
if i is None:
i = len(v) - 1
if i > 1:
recursiveInsertionSort(v, i-1)
while v[i-1]>v[i] and i>0:
v[i-1], v[i]=v[i], v[i-1]
i-=1
这比当前代码更有效,因为它不会为每个递归调用复制列表。这两个版本仍然是O(N**2)
,因此不要指望它与大型数据集上的quicksort
或其他更有效的排序竞争。