次のコードでのスタックフレーム(ない鉱山、それを研究)元のリスト(すなわち、list_
)以上の再帰の間にバウンス(正しく)、およびマージルーチン。スタックフレームの流れ(つまり、Python Tutorを見ていても、どうやって彼らがどう戻ってきたのかは分かりませんが、これは私が以下に述べています)。コードがどのように戻り、質問がプログラムに続くかについての説明。再帰マージソートとPython
def merge(left, right):
if not len(left) or not len(right):
return left or right
result = []
i, j = 0, 0
while (len(result) < len(left) + len(right)):
if left[i] < right[j]:
result.append(left[i])
i+= 1
else:
result.append(right[j])
j+= 1
if i == len(left) or j == len(right):
result.extend(left[i:] or right[j:])
break
return result
def mergesort(list_):
if len(list_) < 2:
return list_
middle = len(list_)//2
left = mergesort(list_[:middle])
right = mergesort(list_[middle:])
return merge(left, right)
list_ = [7,5,2,1,3]
print(mergesort(list_))
我々は大きさ1のリストを取得するまで、私たちはヒット最初の再帰呼び出しは、(我々はなど、リストの左半分をソートし、その後、左半分の左半分にしたい、left
で、ベースケースに当たってください)。これは正常に動作します。私たちは[7,5,2,1,3]から[7,5]〜[7]に進み、ベースケースに当たった。ここまでは順調ですね。 私はスタックフレームが復帰を開始すると期待していますが、実際には何も起こりません。私はそれが7を返すと思うが、次にright
の再帰呼び出しの次のセットにジャンプする。 5が再表示されます。 5は7の直前のスタックフレームに現れました。そのため、物事は逆順に戻ります(これは良いことです)。新しいパラメータは、このように基本ケースをオフに設定し、それは奇妙な取得するのはここだ5.
を返し、5をオフに分割し、単一のリストを作成します。正しいマージステップに進みます。 は、どのようにそれがさらにright
またはleft
に再帰スキップして、「知っている」ん(私はそれをそのままでずっとそのリスト全体を、与えた)と合併するジャンプ?さらに、明示的な指示なしにマージからマージソート関数に戻す方法を知っていて、どこからピックアップするのか正確に知っていますか?誰もがこれにいくつかの光を当てることはできますか?従来のアルゴリズムのテキストやほとんどのビデオは、スタックフレームに対処していないため、ヘルプがゼロでした。
。また、私は、リターンステートメントに実際よりも多くの最終性があったと考えています(つまり、リターンはfxnを終了せず、むしろ値を返します)。 「あなたの機能から何かを戻せば、それだけです!それ以外は何もできません」。それをあまりにも遠くに運んでいる。また、EIPがどのような役割を果たしているかは分かりませんが、これはおそらく助けになるかもしれませんが、私は技術的ではないアプローチが好きです。 – Ryan
引用している文は間違っていないと思います。同じ関数への複数の再帰呼び出しを扱うときにはちょっと混乱します。 'return'は、現在の関数の実行を終了しますが、(その呼び出し元が再帰呼び出しを行う同じ関数であっても)呼び出し元の実行を終了しません。呼び出し元は、一時停止した場所からだけ進みます。したがって、6つのスタックフレームが深く、 'return'ステートメントをヒットした場合、6番目のフレームが終了し、5番目のスタックフレームに戻り、そのコードを実行し続けます。 – Blckknght