Saya tahu konsep umum rekursi. Saya menemukan konsep rekursi ekor sambil mempelajari algoritma quicksort. Dalam video algoritma pengurutan cepat ini dari MIT pada pukul 18:30, profesor mengatakan bahwa ini adalah algoritme rekursif ekor. Tidak jelas bagi saya apa yang dimaksud dengan rekursi ekor sebenarnya.
Adakah yang bisa menjelaskan konsep tersebut dengan contoh yang tepat?
Beberapa jawaban diberikan oleh komunitas SO di sini .
algorithms
reference-request
recursion
Kutu buku
sumber
sumber
Jawaban:
Rekursi ekor adalah kasus rekursi khusus di mana fungsi panggilan tidak lagi menghitung setelah melakukan panggilan rekursif. Misalnya saja fungsinya
adalah ekor rekursif (karena instruksi terakhir adalah panggilan rekursif) sedangkan fungsi ini bukan ekor rekursif:
karena melakukan beberapa perhitungan setelah panggilan rekursif telah kembali.
Rekursi ekor penting karena dapat diimplementasikan lebih efisien daripada rekursi umum. Ketika kita melakukan panggilan rekursif normal, kita harus mendorong alamat pengirim ke tumpukan panggilan kemudian melompat ke fungsi yang dipanggil. Ini berarti bahwa kita memerlukan tumpukan panggilan yang ukurannya linier di kedalaman panggilan rekursif. Ketika kita memiliki rekursi ekor, kita tahu bahwa segera setelah kita kembali dari panggilan rekursif kita juga akan segera kembali, sehingga kita dapat melewatkan seluruh rantai fungsi rekursif yang kembali dan kembali langsung ke pemanggil yang asli. Itu berarti kita tidak memerlukan tumpukan panggilan sama sekali untuk semua panggilan rekursif, dan dapat mengimplementasikan panggilan terakhir sebagai lompatan sederhana, yang menghemat ruang bagi kita.
sumber
def recurse(x): if x < 0 return 1; for i in range 100{ (do calculations) recurse(x)}
Secara sederhana, rekursi ekor adalah rekursi di mana kompiler dapat mengganti panggilan rekursif dengan perintah "goto", sehingga versi yang dikompilasi tidak harus meningkatkan kedalaman tumpukan.
Kadang-kadang merancang fungsi rekursif ekor mengharuskan Anda perlu membuat fungsi pembantu dengan parameter tambahan.
Sebagai contoh, ini bukan fungsi rekursif ekor:
Tapi ini adalah fungsi rekursif ekor:
karena kompiler dapat menulis ulang fungsi rekursif ke yang non-rekursif, menggunakan sesuatu seperti ini (kodesemu):
Aturan untuk kompiler sangat sederhana: Ketika Anda menemukan "
return thisfunction(newparameters);
", ganti dengan "parameters = newparameters; goto start;
". Tetapi ini hanya dapat dilakukan jika nilai yang dikembalikan oleh panggilan rekursif dikembalikan secara langsung.Jika semua panggilan rekursif dalam suatu fungsi dapat diganti seperti ini, maka itu adalah fungsi ekor-rekursif.
sumber
Jawaban saya didasarkan pada penjelasan yang diberikan dalam buku Struktur dan Interpretasi Program Komputer . Saya sangat merekomendasikan buku ini kepada para ilmuwan komputer.
Pendekatan A: Proses Rekursif Linear
Bentuk proses untuk Pendekatan A terlihat seperti ini:
Pendekatan B: Proses Iteratif Linier
Bentuk proses untuk Pendekatan B terlihat seperti ini:
Proses Iteratif Linear (Pendekatan B) berjalan dalam ruang konstan walaupun prosesnya adalah prosedur rekursif. Juga harus dicatat bahwa dalam pendekatan ini satu set variabel menentukan keadaan proses pada setiap titik yaitu.
{product, counter, max-count}
. Ini juga merupakan teknik di mana rekursi ekor memungkinkan optimisasi kompiler.Dalam Pendekatan A, terdapat lebih banyak informasi tersembunyi yang disimpan oleh juru bahasa yang pada dasarnya merupakan rantai operasi yang ditangguhkan.
sumber
Ekor-rekursi adalah bentuk rekursi di mana panggilan rekursif adalah instruksi terakhir dalam fungsi (dari situlah bagian ekor berasal). Selain itu, panggilan rekursif tidak boleh dibuat dengan referensi ke sel memori yang menyimpan nilai sebelumnya (referensi selain parameter fungsi). Dengan cara ini, kami tidak peduli dengan nilai-nilai sebelumnya dan satu frame stack mencukupi untuk semua panggilan rekursif; ekor-rekursi adalah salah satu cara untuk mengoptimalkan algoritma rekursif. Keuntungan lain / optimasi adalah bahwa ada cara mudah untuk mengubah algoritma rekursif ekor menjadi yang setara yang menggunakan iterasi bukan rekursi. Jadi ya, algoritma untuk quicksort memang ekor-rekursif.
Ini adalah versi yang berulang:
sumber