Saya perlu membuat algoritma rekursif untuk melihat apakah pohon biner adalah pohon pencarian biner serta menghitung berapa banyak cabang lengkap yang ada (simpul orangtua dengan simpul anak kiri dan kanan) dengan asumsi variabel penghitungan global. Ini adalah tugas untuk kelas struktur data saya.
Sejauh ini saya punya
void BST(tree T) {
if (T == null) return
if ( T.left and T.right) {
if (T.left.data < T.data or T.right.data > T.data) {
count = count + 1
BST(T.left)
BST(T.right)
}
}
}
Tetapi saya tidak dapat benar-benar memahami hal ini. Saya tahu bahwa algoritma ini tidak akan menyelesaikan masalah karena hitungannya akan nol jika pernyataan kedua jika tidak benar.
Adakah yang bisa membantu saya dalam hal ini?
algorithms
recursion
trees
OghmaOsiris
sumber
sumber
<
didefinisikan pada node?true
ataufalse
?Jawaban:
Seperti yang telah ditunjukkan orang lain dalam komentar, Anda benar-benar memiliki dua fungsi yang tidak terkait di sini: menguji apakah pohon itu adalah pohon pencarian, dan menghitung cabang lengkap. Kecuali jika penugasan secara khusus memanggilnya, saya akan menulis dua fungsi terpisah.
Mari kita lihat jumlah menghitung cabang lengkap terlebih dahulu. Itu berarti menghitung node yang memiliki anak kiri dan anak kanan. Maka Anda perlu menambah penghitung (
count = count + 1
) saat keduanyaT.left
danT.right
bukan nol (tidakT.left.data
danT.right.data
: data tidak masalah untuk tugas ini).Selanjutnya, Anda perlu menjelajahi subtree kiri bahkan jika subtree kanan kosong, dan Anda perlu menjelajahi subtree kanan bahkan jika subtree kiri kosong. Jadi perhatikan di mana Anda melakukan panggilan rekursif.
Untuk menguji apakah pohon itu pohon pencarian, Anda perlu memeriksa nilai data. Anda sudah mendapatkan sesuatu yang dekat dengan perbandingan yang tepat; tidak benar. Tulis beberapa pohon contoh dengan berbagai bentuk (tidak terlalu besar, 2 hingga 5 node) dan jalankan algoritma Anda pada mereka untuk melihat apa yang terjadi.
Anda masih perlu menemukan tempat untuk meletakkan hasil pemeriksaan validitas. Sekali lagi, perhatikan di mana Anda melakukan panggilan rekursif (jika Anda hanya melakukan bagian ini, ada beberapa solusi, tetapi pada tahap ini jangan khawatir jika Anda hanya melihat satu).
Terakhir, setelah Anda berhasil menulis kedua fungsi secara terpisah, dan Anda telah mengujinya pada beberapa contoh, kumpulkan semuanya dengan hati-hati (jika diperlukan oleh penugasan).
sumber
Dalam hal-hal seperti ini, seringkali lebih mudah untuk berpikir mundur, jadi pertimbangkan dulu apa yang Anda butuhkan. Dari deskripsi Anda, mari daftarkan mereka:
OK, itu daftar yang cukup singkat, ini harus dapat dikelola. Mari kita mulai dengan metode kosong dan saya akan menambahkan deskripsi tentang apa yang seharusnya terjadi.
Sekarang validitas. Bagaimana Anda memeriksa validitas? Dalam obrolan Anda mengatakan pohon itu valid "jika ... semua anak yang tersisa lebih kecil dari orang tua, dan anak yang tepat lebih besar dari orang tua." Saya yakin Anda bermaksud untuk mengizinkan kesetaraan juga. Itu pasti
t.left.value <= t.value <= t.right.value
.Tetapi bagaimana jika salah satu dari anak-anak itu hilang? Dari apa yang Anda katakan, saya yakin Anda tahu simpul masih valid jika salah satu (atau keduanya) hilang. Mari kita tambahkan ini, restrukturisasi sedikit:
OK, kita sekarang tahu apakah simpul ini valid. Bagaimana kita memeriksa apakah seluruh pohon itu valid? Itu tidak ada dalam array, jadi kita mungkin tidak bisa / tidak ingin mengulanginya secara linear. Tugas Anda memberikan jawabannya: rekursi. Tetapi bagaimana kita mengumpulkan jawaban menggunakan rekursi? Kami memiliki akses ke tiga informasi, apakah simpul ini valid, dan hasil panggilan yang menanyakan apakah simpul kiri dan kanan itu valid. Jelas pohon itu hanya valid jika ketiganya benar.
Jika Anda memperhatikan, itu bahkan memberi tahu kami apa yang harus dikembalikan oleh fungsi kami.
Sekarang, bagaimana kita mengintegrasikan penghitungan? Anda mengatakan apa yang diperhitungkan ("simpul orangtua dengan simpul anak kiri dan kanan"), dan itu seharusnya tidak sulit untuk diterjemahkan ke dalam kode aktual. Periksa apakah kondisi itu terpenuhi dan tambahkan penghitung dengan tepat. Ingat saja ini harus di suatu tempat di mana ia akan tercapai setiap kali itu benar.
Dan tentu saja saya telah meninggalkan beberapa detail seperti kondisi berhenti rekursi dan memeriksa nol.
sumber
Tiga komentar saya di atas adalah tiga petunjuk untuk masalah dengan kode Anda.
node1.value < node2.value
if
benar, apakah Anda yakin itu yang ingin Anda lakukan? By the way, Anda mungkin ingin memeriksa bahwa jika pernyataan melakukan apa yang Anda inginkan.sumber