私は3つの美しいクイックソートの話を見て、クイックソートをいじっていました。私のPythonでの実装は、cと非常によく似ていました(ピボットを選択し、その周りをパーティション分割して、より小さなパーティションとより大きなパーティションを繰り返します)。私はそれがpythonicではないと思った。
つまり、これはPythonでリスト内包表記を使用した実装です。
def qsort(list):
if list == []:
return []
pivot = list[0]
l = qsort([x for x in list[1:] if x < pivot])
u = qsort([x for x in list[1:] if x >= pivot])
return l + [pivot] + u
再帰メトqsortRと呼びましょう。ここで、qsortRの実行がlarge(r)リストのqsortよりもはるかに遅いことに気付きました。実際には、再帰法の1000要素でも「最大再帰深度をcmp単位で超えました」。sys.setrecursionlimitでリセットしました。
いくつかの数字:
list-compr 1000 elems 0.491770029068
recursion 1000 elems 2.24620914459
list-compr 2000 elems 0.992327928543
recursion 2000 elems 7.72630095482
すべてのコードはここにあります。
いくつか質問があります。
- リスト内包表記が非常に速いのはなぜですか?
- Pythonでの再帰の制限に関するいくつかの啓蒙。最初に100000に設定しましたが、どのような場合に注意する必要がありますか?
- (「末尾再帰の最適化」とは正確にはどういう意味ですか、どのように実行されますか?)
- 1000000個の要素を並べ替えようとすると、ラップトップのメモリが占有されます(再帰メソッドを使用)。非常に多くの要素を並べ替えたい場合はどうすればよいですか?どのような最適化が可能ですか?