Saya memiliki banyak objek dalam struktur datar. Benda-benda ini memiliki ID
dan ParentID
properti sehingga mereka dapat diatur di pohon. Mereka tidak dalam urutan tertentu. Setiap ParentID
properti tidak harus cocok dengan ID
dalam struktur. Oleh karena itu mereka mungkin beberapa pohon yang muncul dari benda-benda ini.
Bagaimana Anda memproses objek-objek ini untuk membuat pohon yang dihasilkan?
Saya tidak jauh dari solusi tapi saya yakin itu masih jauh dari optimal ...
Saya perlu membuat pohon ini untuk kemudian memasukkan data ke dalam database, dalam urutan yang benar.
Tidak ada referensi melingkar. Node adalah RootNode ketika ParentID == null atau ketika ParentID tidak dapat ditemukan di objek lain
algorithm
tree
language-agnostic
Costo
sumber
sumber
Jawaban:
Menyimpan ID dari objek dalam pemetaan tabel hash ke objek tertentu. Hitung semua objek dan temukan induknya jika ada dan perbarui pointer induknya.
sumber
Berdasarkan jawaban Mehrdad Afshari dan komentar Andrew Hanlon untuk sebuah speedup, inilah pendapat saya.
Perbedaan penting dengan tugas asli: Simpul root memiliki ID == parentID.
sumber
Berikut adalah algoritma JavaScript sederhana untuk mem-parsing tabel datar ke struktur pohon induk / anak yang berjalan dalam waktu N:
sumber
console.log(JSON.stringify(root, null, 2));
untuk mencetak hasil cetak dengan cantik.Solusi python
Sebagai contoh:
Menghasilkan:
sumber
def recurse(id, pages): for row in rows: if row['id'] == id: print(f'''{row['id']}:{row['parent_id']} {row['path']} {row['title']}''') recurse(row['id'], rows)
Versi JS yang mengembalikan satu root atau array root yang masing-masing akan memiliki properti array Kids yang berisi anak-anak terkait. Tidak bergantung pada input yang dipesan, padat kompak, dan tidak menggunakan rekursi. Nikmati!
sumber
Temukan versi JavaScript yang mengagumkan di sini: http://oskarhane.com/create-a-nested-array-recursively-in-javascript/
Katakanlah Anda memiliki array seperti ini:
Dan Anda ingin memiliki objek bersarang seperti ini:
Inilah fungsi rekursif yang membuatnya terjadi.
Bahasa:
sumber
Bagi siapa pun yang tertarik dengan versi C # dari solusi Eugene, perhatikan bahwa node_list diakses sebagai peta, jadi gunakan Kamus saja.
Perlu diingat bahwa solusi ini hanya berfungsi jika tabel diurutkan berdasarkan parent_id .
Node didefinisikan sebagai berikut.
sumber
new Node { parent_id = 7, id = 9 },
mencegahnode_list.Add(item.id, item);
untuk menyelesaikan karena Kunci tidak dapat diulang; itu salah ketik; jadi, alih-alih id = 9 , ketik id = 8Saya menulis solusi generik dalam C # secara longgar berdasarkan jawaban @Mehrdad Afshari:
sumber
Berikut adalah solusi java dari jawaban oleh Mehrdad Afshari.
sumber
Samar-samar karena pertanyaannya bagi saya, saya mungkin akan membuat peta dari ID ke objek yang sebenarnya. Di pseudo-java (saya tidak memeriksa apakah ia berfungsi / mengkompilasi), itu mungkin seperti:
Dan untuk mencari setiap orang tua:
Dengan menggunakan kembali
getRealObject(ID)
dan melakukan peta dari objek ke koleksi objek (atau ID mereka), Anda mendapatkan peta orangtua-anak-anak juga.sumber
Saya dapat melakukan ini dalam 4 baris kode dan O (n log n) waktu, dengan asumsi bahwa Kamus adalah sesuatu seperti TreeMap.
EDIT : Ok, dan sekarang saya membaca bahwa beberapa parentID palsu, jadi lupakan yang di atas, dan lakukan ini:
sumber
Sebagian besar jawaban menganggap Anda ingin melakukan ini di luar basis data. Jika pohon Anda relatif statis dan Anda hanya perlu memetakan pohon-pohon tersebut ke dalam basis data, Anda mungkin ingin mempertimbangkan untuk menggunakan representasi kumpulan bersarang di sisi basis data. Lihatlah buku-buku karya Joe Celko (atau di sini untuk ikhtisar oleh Celko).
Jika dikaitkan dengan Oracle dbs, periksa CONNECT BY mereka untuk pendekatan SQL langsung.
Dengan pendekatan mana pun, Anda bisa melewatkan pemetaan pohon sebelum memuat data ke dalam basis data. Hanya berpikir saya akan menawarkan ini sebagai alternatif, mungkin benar-benar tidak sesuai untuk kebutuhan spesifik Anda. Seluruh bagian "urutan yang tepat" dari pertanyaan awal agak menyiratkan Anda memerlukan perintah untuk menjadi "benar" di db karena alasan tertentu? Ini mungkin mendorong saya ke arah penanganan pohon di sana juga.
sumber
Ini tidak persis sama dengan apa yang dicari si penanya, tetapi saya mengalami kesulitan membungkus kepala saya di sekitar jawaban yang diuraikan secara ambigu yang disediakan di sini, dan saya masih berpikir jawaban ini sesuai dengan judulnya.
Jawaban saya adalah untuk memetakan struktur datar ke pohon objek langsung di mana semua yang Anda miliki adalah
ParentID
pada setiap objek.ParentID
adalahnull
atau0
jika itu adalah root. Berlawanan dengan penanya, saya menganggap semuaParentID
poin valid untuk hal lain dalam daftar:sumber
di sini adalah implementasi ruby:
Ini akan katalog berdasarkan nama atribut atau hasil pemanggilan metode.
sumber
Jawaban yang diterima terlihat terlalu rumit bagi saya, jadi saya menambahkan versi Ruby dan NodeJS
Misalkan daftar node datar memiliki struktur berikut:
Fungsi-fungsi yang akan mengubah struktur daftar datar di atas menjadi pohon terlihat dengan cara berikut
untuk Ruby:
untuk NodeJS:
sumber
null
kebutuhanundefined
null == undefined => true
di NodeJSsalah satu cara elegan untuk melakukan ini adalah untuk mewakili item dalam daftar sebagai string yang memegang daftar titik yang dipisahkan dari orang tua, dan akhirnya nilai:
Saat merakit pohon, Anda akan berakhir dengan sesuatu seperti:
Saya memiliki pustaka konfigurasi yang mengimplementasikan konfigurasi timpa ini (pohon) dari argumen baris perintah (daftar). Algoritma untuk menambahkan satu item ke daftar ke pohon ada di sini .
sumber
Apakah Anda hanya menggunakan atribut tersebut? Jika tidak, mungkin menyenangkan untuk membuat array node anak, di mana Anda dapat menggilir semua objek ini sekali untuk membangun atribut seperti itu. Dari sana, pilih simpul dengan anak-anak tetapi tidak ada orang tua dan iteratif membangun pohon Anda dari atas ke bawah.
sumber
versi java
sumber