Kombinasi sekuensialisasi pra, pasca, dan berurutan manakah yang unik?

28

Kami tahu post-order,

post L(x)     => [x]
post N(x,l,r) => (post l) ++ (post r) ++ [x]

dan pre-order

pre L(x)     => [x]
pre N(x,l,r) => [x] ++ (pre l) ++ (pre r)

dan resp traversal berurutan. sekuensialisasi.

in L(x)     => [x]
in N(x,l,r) => (in l) ++ [x] ++ (in r)

Orang dapat dengan mudah melihat bahwa keduanya tidak menggambarkan pohon yang diberikan secara unik, bahkan jika kita mengasumsikan kunci / label berbeda berpasangan.

Kombinasi mana dari ketiganya yang bisa digunakan untuk tujuan itu dan mana yang tidak bisa?

Jawaban positif harus mencakup algoritma (efisien) untuk merekonstruksi pohon dan bukti (ide) mengapa itu benar. Jawaban negatif harus memberikan contoh tandingan, yaitu pohon yang berbeda yang memiliki representasi yang sama.

Raphael
sumber

Jawaban:

16

Pertama, saya akan berasumsi bahwa semua elemen berbeda. Tidak ada jumlah sekuensialisasi yang akan memberi tahu Anda bentuk pohon dengan elemen [3,3,3,3,3]. Dimungkinkan untuk merekonstruksi beberapa pohon dengan elemen duplikat, tentu saja; Saya tidak tahu kondisi apa yang cukup bagus.

Melanjutkan hasil negatif, Anda tidak dapat sepenuhnya membangun kembali pohon biner dari sekuensialisasi pra-pesanan dan pasca-pesanan saja. [1,2]preorder, [2,1]post-order harus ada 1di root, tetapi 2bisa berupa anak kiri atau anak kanan. Jika Anda tidak peduli dengan ambiguitas ini, Anda dapat merekonstruksi pohon dengan algoritma berikut:

  • Biarkan menjadi traversal pre-order dan menjadi traversal post-order. Kita harus memiliki , dan ini adalah akar dari pohon.[ y n , ... , y 1 ] x 1 = y 1[x1,,xn][yn,,y1]x1=y1
  • y 2 x 2 = y 2 [ x 2 , ... , x n ] [ y n , ... , y 2 ]x2 adalah anak paling kiri dari root, dan adalah anak paling kanan. Jika , simpul root tidak waspada; ulangi dan untuk membuat subtree tunggal.y2x2=y2[x2,,xn][yn,,y2]
  • Kalau tidak, biarkan dan menjadi indeks sedemikian rupa sehingga dan . adalah traversal pre-order dari subtree kiri, dengan subtree kanan, dan juga untuk post-order. Subtree kiri memiliki elemen , dan subtree kanan memiliki elemen . Perulangan satu kali untuk setiap subtree. Omong-omong, metode ini digeneralisasikan ke pohon dengan percabangan yang sewenang-wenang. Dengan percabangan sewenang-wenang, cari tahu sejauh mana subtree kiri dan potong elemen dari kedua daftar, lalu ulangi untuk memotong subtree kedua dari kiri, dan seterusnya.j x 2 = y i y 2 = x j [ x 2 , ... , x j - 1 ] [ x j , ... , x n ] j - 2 = n - i + 1 i - 2 = n - j + 1 j - 2ijx2=yiy2=xj[x2,,xj1][xj,,xn]j2=ni+1i2=nj+1
    j2

Seperti yang dinyatakan, waktu berjalan adalah dengan kasus terburuk (dalam kasus dengan dua anak, kami mencari setiap daftar lineraly). Anda dapat mengubahnya menjadi jika Anda memproses ulang daftar untuk membangun sebuah struktur peta hingga dari nilai elemen ke posisi dalam daftar input . Juga gunakan array atau peta terbatas untuk beralih dari indeks ke nilai; tetap berpegang pada indeks global, sehingga panggilan rekursif akan menerima seluruh peta dan mengambil rentang sebagai argumen untuk mengetahui apa yang harus ditindaklanjuti.Θ ( n 2 ) O ( nO(n2)Θ(n2)O(nlg(n))nlg(n)

Dengan traversal pre-order dan traversal in-order , Anda dapat membangun kembali pohon sebagai berikut:[x1,,xn][z1,,zn]

  • Root adalah kepala traversal pre-order .x1
  • Biarkan menjadi indeks sedemikian rupa sehingga . Kemudian adalah traversal berurutan dari anak kiri dan adalah traversal berurutan dari anak kanan. Dengan jumlah elemen, adalah traversal pre-order dari anak kiri dan dari anak kanan. Berulang untuk membangun sub pohon kiri dan kanan.z k = x 1 [ z 1 , ... , z k - 1 ] [ z k + 1 , ... , z n ] [ x 2 , ... , x k ] [ x k + 1 , ... , x n ]kzk=x1[z1,,zk1][zk+1,,zn][x2,,xk][xk+1,,xn]

Sekali lagi, algoritma ini adalah seperti yang dinyatakan, dan dapat dilakukan dalam jika daftar diolah menjadi peta terbatas dari nilai ke posisi.O ( nO(n2)O(nlg(n))

Post-order plus in-order tentu saja simetris.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
Apakah ada salah ketik di sini: "[1,2] preorder, [1,2] post-order harus memiliki 1 di root, tetapi 2 dapat berupa anak kiri atau anak kanan." pohon akan menjadi [2,1] bukan [1,2] apakah 2 adalah anak kiri atau kanan. Juga, maksud Anda jika preorder dan postorder diberikan, kami tidak dapat merekonstruksi pohon, atau maksud Anda jika kami hanya diberikan satu saja maka kami tidak dapat merekonstruksi pohon itu?
CEGRD
@CEGRD Memang, postorder itu salah ketik. Contoh menunjukkan bahwa Anda tidak dapat sepenuhnya merekonstruksi pohon dalam kasus ini: Anda tidak bisa tahu apakah 2itu anak kiri atau anak kanan. Ini sesuai dengan kasus “subtree tunggal” dari algoritma rekonstruksi.
Gilles 'SO- berhenti bersikap jahat'
bagaimana perubahan ini jika kita tahu itu Binary Search Tree? untuk kasus sederhana dalam contoh Anda ([1,2] preorder, [2,1] post-order) kami akan dapat menentukan bahwa root adalah 1 dan 2 adalah anak yang tepat (karena 2 lebih besar dari 1) ... benar?
fersarr