Banyak algoritma akan menentukan bahwa duplikat dikecualikan. Sebagai contoh, algoritma contoh dalam buku Algoritma MIT biasanya menyajikan contoh tanpa duplikat. Cukup sepele untuk mengimplementasikan duplikat (baik sebagai daftar di simpul, atau dalam satu arah tertentu).
Sebagian besar (yang pernah saya lihat) menetapkan anak kiri sebagai <= dan anak kanan sebagai>. Secara praktis, BST yang memungkinkan anak-anak dari kanan atau kiri sama dengan simpul akar, akan memerlukan langkah komputasi ekstra untuk menyelesaikan pencarian di mana duplikat node diperbolehkan.
Yang terbaik adalah menggunakan daftar di simpul untuk menyimpan duplikat, karena menyisipkan nilai '=' ke satu sisi simpul memerlukan penulisan ulang pohon di sisi itu untuk menempatkan simpul sebagai anak, atau simpul ditempatkan sebagai grand -cild, di beberapa titik di bawah ini, yang menghilangkan beberapa efisiensi pencarian.
Anda harus ingat, sebagian besar contoh ruang kelas disederhanakan untuk menggambarkan dan menyampaikan konsep. Mereka tidak layak jongkok dalam banyak situasi dunia nyata. Tetapi pernyataan, "setiap elemen memiliki kunci dan tidak ada dua elemen yang memiliki kunci yang sama", tidak dilanggar dengan menggunakan daftar pada simpul elemen.
Jadi, pergilah dengan apa yang dikatakan buku struktur data Anda!
Edit:
Definisi Universal dari Pohon Pencarian Biner melibatkan penyimpanan dan pencarian kunci berdasarkan melintasi struktur data di salah satu dari dua arah. Dalam arti pragmatis, itu berarti jika nilainya <>, Anda melintasi struktur data di salah satu dari dua 'arah'. Jadi, dalam hal itu, nilai duplikat sama sekali tidak masuk akal.
Ini berbeda dari BSP, atau partisi pencarian biner, tetapi tidak semuanya berbeda. Algoritme untuk pencarian memiliki satu dari dua arah untuk 'perjalanan', atau itu dilakukan (berhasil atau tidak.) Jadi saya minta maaf karena jawaban asli saya tidak membahas konsep 'definisi universal', karena duplikat benar-benar berbeda topik (sesuatu yang Anda tangani setelah pencarian yang berhasil, bukan sebagai bagian dari pencarian biner.)
Jika pohon pencarian biner Anda adalah pohon merah-hitam, atau Anda berniat untuk segala jenis operasi "rotasi pohon", duplikat node akan menyebabkan masalah. Bayangkan aturan pohon Anda adalah ini:
kiri <root <= kanan
Sekarang bayangkan sebuah pohon sederhana yang akarnya 5, anak kiri nihil, dan anak kanan 5. Jika Anda melakukan rotasi kiri pada root, Anda akan mendapatkan 5 di anak kiri dan 5 di root dengan anak kanan menjadi nihil. Sekarang sesuatu di pohon kiri sama dengan root, tetapi aturan Anda di atas diasumsikan sebagai <root.
Saya menghabiskan waktu berjam-jam untuk mencari tahu mengapa pohon-pohon merah / hitam saya kadang-kadang melintasi tidak teratur, masalahnya adalah apa yang saya jelaskan di atas. Semoga seseorang membaca ini dan menghemat berjam-jam untuk debugging di masa depan!
sumber
left <= node <= right
, atau hanya masukkan sebelum pertama terjadinya nilai.Ketiga definisi tersebut dapat diterima dan benar. Mereka menentukan variasi BST yang berbeda.
Buku struktur data perguruan tinggi Anda gagal menjelaskan bahwa definisi itu bukan satu-satunya yang mungkin.
Tentu saja, memperbolehkan duplikat menambah kerumitan. Jika Anda menggunakan definisi "kiri <= root <kanan" dan Anda memiliki pohon seperti:
kemudian menambahkan kunci duplikat "3" ke pohon ini akan menghasilkan:
Perhatikan bahwa duplikat tidak dalam level yang berdekatan.
Ini adalah masalah besar ketika memungkinkan duplikat dalam representasi BST seperti yang di atas: duplikat dapat dipisahkan oleh sejumlah level, jadi memeriksa keberadaan duplikat tidak sesederhana hanya memeriksa anak-anak langsung dari sebuah node.
Pilihan untuk menghindari masalah ini adalah untuk tidak mewakili duplikat secara struktural (sebagai node terpisah) melainkan menggunakan penghitung yang menghitung jumlah kemunculan kunci. Contoh sebelumnya akan memiliki pohon seperti:
dan setelah penyisipan kunci duplikat "3" itu akan menjadi:
Ini menyederhanakan operasi pencarian, penghapusan dan penyisipan, dengan mengorbankan beberapa byte tambahan dan operasi penghitung.
sumber
Dalam BST, semua nilai turun di sisi kiri node kurang dari (atau sama dengan, lihat nanti) node itu sendiri. Demikian pula, semua nilai turun di sisi kanan sebuah node lebih besar dari (atau sama dengan) nilai node (a) .
Beberapa BST dapat memilih untuk mengizinkan nilai duplikat, karenanya kualifikasi "atau sama dengan" di atas.
Contoh berikut dapat menjelaskan:
Ini menunjukkan BST yang memungkinkan duplikat - Anda dapat melihat bahwa untuk menemukan nilai, Anda mulai pada simpul akar dan turun subtree kiri atau kanan tergantung pada apakah nilai pencarian Anda kurang dari atau lebih besar dari nilai node.
Ini dapat dilakukan secara rekursif dengan sesuatu seperti:
dan menyebutnya dengan:
Duplikat menambah sedikit kerumitan karena Anda mungkin perlu terus mencari begitu Anda telah menemukan nilai Anda untuk node lain dengan nilai yang sama.
(a) Anda benar - benar dapat mengurutkannya ke arah yang berlawanan jika Anda ingin asalkan Anda menyesuaikan cara Anda mencari kunci tertentu. BST hanya perlu mempertahankan beberapa urutan, apakah naik atau turun tidak relevan.
sumber
Dalam buku "Pengantar algoritma", edisi ketiga, oleh Cormen, Leiserson, Rivest dan Stein, pohon pencarian biner (BST) secara eksplisit didefinisikan sebagai memungkinkan duplikat . Ini dapat dilihat pada gambar 12.1 dan berikut ini (halaman 287):
Selain itu, pohon merah-hitam kemudian didefinisikan pada halaman 308 sebagai:
Oleh karena itu, pohon merah-hitam yang didefinisikan dalam buku ini mendukung duplikat.
sumber
Definisi apa pun valid. Selama Anda konsisten dalam implementasi Anda (selalu menempatkan simpul yang sama di sebelah kanan, selalu menempatkannya di sebelah kiri, atau tidak pernah mengizinkannya) maka Anda baik-baik saja. Saya pikir itu paling umum untuk tidak mengizinkan mereka, tetapi masih BST jika mereka diizinkan dan ditempatkan di kiri atau kanan.
sumber
Bekerja pada implementasi pohon merah-hitam Saya mendapatkan masalah memvalidasi pohon dengan beberapa kunci sampai saya menyadari bahwa dengan rotasi insert merah-hitam, Anda harus melonggarkan kendala untuk
left <= root <= right
Karena tidak ada dokumentasi yang saya lihat diperbolehkan untuk kunci duplikat dan saya tidak ingin menulis ulang metode rotasi untuk menjelaskannya, saya hanya memutuskan untuk memodifikasi node saya untuk memungkinkan beberapa nilai dalam node, dan tidak ada kunci duplikat di pohon.
sumber
Tiga hal yang Anda katakan semuanya benar.
Saya kira Anda dapat membalik pohon Anda dan meletakkan kunci yang lebih kecil di sebelah kanan, tetapi benar-benar konsep "kiri" dan "kanan" hanya itu: konsep visual untuk membantu kami berpikir tentang struktur data yang tidak benar-benar memiliki kiri atau benar, jadi itu tidak masalah.
sumber
Saya mungkin harus pergi dan menggali buku-buku algoritma saya, tetapi dari atas kepala saya (3) adalah bentuk kanonik.
(1) atau (2) hanya muncul ketika Anda mulai mengizinkan duplikat node dan Anda menempatkan duplikat node di pohon itu sendiri (daripada node yang berisi daftar).
sumber
>=
. Ideal tergantung pada kebutuhan Anda, tetapi jika Anda memiliki banyak nilai duplikat, dan Anda membiarkan duplikat itu ada dalam struktur, pertama Anda dapat menjadi linier - yaitu O (n).Duplikat Kunci • Apa yang terjadi jika ada lebih dari satu item data dengan kunci yang sama? - Ini menghadirkan sedikit masalah di pohon merah-hitam. - Sangat penting bahwa node dengan kunci yang sama didistribusikan di kedua sisi node lain dengan kunci yang sama. - Yaitu, jika kunci tiba dalam urutan 50, 50, 50, • Anda ingin 50 detik untuk pergi ke kanan yang pertama, dan 50 ketiga untuk pergi ke kiri yang pertama. • Kalau tidak, pohon menjadi tidak seimbang. • Ini bisa ditangani oleh beberapa jenis proses pengacakan dalam algoritma penyisipan. - Namun, proses pencarian menjadi lebih rumit jika semua item dengan kunci yang sama harus ditemukan. • Lebih mudah untuk melarang item dengan kunci yang sama. - Dalam diskusi ini kami akan menganggap duplikat tidak diperbolehkan
Seseorang dapat membuat daftar tertaut untuk setiap simpul pohon yang berisi kunci duplikat dan menyimpan data dalam daftar.
sumber
Saya hanya ingin menambahkan beberapa informasi ke apa yang dijawab @Robert Paulson.
Mari kita asumsikan bahwa simpul berisi kunci & data. Jadi node dengan kunci yang sama mungkin berisi data berbeda.
(Jadi pencarian harus menemukan semua node dengan kunci yang sama)
1) & 2) berfungsi dengan baik jika pohon tidak memiliki fungsi terkait rotasi untuk mencegah kemiringan.
Tetapi formulir ini tidak berfungsi dengan pohon AVL atau pohon Merah-Hitam , karena rotasi akan mematahkan prinsipal.
Dan bahkan jika pencarian () menemukan node dengan kunci, itu harus melintasi ke simpul daun untuk node dengan kunci duplikat.
Membuat kerumitan waktu untuk pencarian = theta (logN)
3) akan bekerja dengan baik dengan segala bentuk BST dengan fungsi terkait rotasi.
Tetapi pencarian akan mengambil O (n) , merusak tujuan menggunakan BST.
Katakanlah kita memiliki pohon seperti di bawah ini, dengan 3) pokok.
Jika kita mencari (12) di pohon ini, bahkan kita menemukan 12 di root, kita harus terus mencari anak kiri & kanan untuk mencari kunci duplikat.
Ini membutuhkan waktu O (n) seperti yang saya katakan.
4) adalah favorit pribadi saya. Misalkan saudara berarti simpul dengan kunci yang sama.
Kita dapat mengubah pohon di atas menjadi di bawah.
Sekarang setiap pencarian akan mengambil O (logN) karena kami tidak perlu melintasi anak-anak untuk kunci duplikat.
Dan prinsipal ini juga bekerja dengan baik dengan AVL atau RB tree .
sumber
Relasi pemesanan elemen <= adalah urutan total sehingga relasi harus refleksif tetapi umumnya pohon pencarian biner (alias BST) adalah pohon tanpa duplikat.
Kalau tidak, jika ada duplikat Anda perlu menjalankan dua kali atau lebih fungsi penghapusan yang sama!
sumber