ดูเหมือนว่าทุกที่ที่ฉันมองมีการใช้โครงสร้างข้อมูลโดยใช้ต้นไม้สีแดงดำ ( std::set
ใน C ++, SortedDictionary
ใน C #, ฯลฯ )
มีต้นไม้ปกคลุม (a, b), สีแดง - ดำและ AVL ในชั้นเรียนอัลกอริทึมของฉันนี่คือสิ่งที่ฉันได้ออกไป (จากการถามอาจารย์, มองผ่านหนังสือสองสามเล่มและ googling เล็กน้อย):
- ต้นไม้ AVL มีความลึกเฉลี่ยน้อยกว่าต้นไม้สีแดงดำดังนั้นการค้นหาค่าในต้นไม้ AVL จึงเร็วขึ้นอย่างต่อเนื่อง
- ต้นไม้สีแดงดำทำการเปลี่ยนแปลงโครงสร้างน้อยกว่าเพื่อความสมดุลตัวเองมากกว่าต้นไม้ AVL ซึ่งอาจทำให้พวกเขาเร็วขึ้นสำหรับการแทรก / ลบ ฉันกำลังพูดถึงสิ่งที่อาจเกิดขึ้นเพราะสิ่งนี้จะขึ้นอยู่กับต้นทุนของการเปลี่ยนแปลงโครงสร้างของต้นไม้เนื่องจากมันจะขึ้นอยู่กับรันไทม์และการดำเนินการ (อาจแตกต่างกันโดยสิ้นเชิงในภาษาที่ใช้งานได้เมื่อต้นไม้ไม่เปลี่ยนรูป)
มีมาตรฐานออนไลน์มากมายที่เปรียบเทียบ AVL กับต้นไม้สีแดง - ดำ แต่สิ่งที่ทำให้ฉันสะดุดคือศาสตราจารย์ของฉันพูดโดยทั่วไปว่าโดยปกติคุณจะทำสองอย่าง:
- ไม่ว่าคุณจะไม่สนใจเรื่องประสิทธิภาพมากนักซึ่งในกรณีนี้ความแตกต่างระหว่าง 10-20% ของ AVL กับสีแดง - ดำในกรณีส่วนใหญ่ไม่สำคัญเลย
- หรือคุณสนใจเกี่ยวกับการแสดงอย่างมากในกรณีที่คุณทิ้งทั้งต้นไม้ AVL และต้นไม้สีแดงดำและไปกับต้นไม้ B ซึ่งสามารถปรับแต่งให้ทำงานได้ดีขึ้นมาก (หรือ (a, b) - ต้นไม้ฉัน ฉันจะเอาของทั้งหมดใส่ตะกร้าใบเดียว)
สาเหตุที่เป็นเพราะ B-tree เก็บข้อมูลในหน่วยความจำให้แน่นมากขึ้น (โหนดหนึ่งมีค่าหลายค่า) จะมีแคชน้อยกว่ามาก คุณสามารถปรับแต่งการใช้งานตามกรณีการใช้งานและทำให้ลำดับของทรี B ขึ้นอยู่กับขนาดแคชของ CPU เป็นต้น
ปัญหาคือฉันไม่สามารถหาเกือบทุกแหล่งที่จะวิเคราะห์การใช้งานจริงของการนำต้นไม้ค้นหาไปใช้บนฮาร์ดแวร์ที่ทันสมัย ฉันได้ดูหนังสือหลายเล่มเกี่ยวกับอัลกอริทึมและไม่พบสิ่งใดที่จะเปรียบเทียบสายพันธุ์ของต้นไม้ที่แตกต่างกันด้วยกันนอกเหนือจากการแสดงว่ามีความลึกเฉลี่ยที่น้อยกว่าอีกเล่มหนึ่ง (ซึ่งจริงๆแล้วไม่ได้พูดมาก ในโปรแกรมจริง)
ที่ถูกกล่าวว่ามีเหตุผลพิเศษหรือไม่ที่จะใช้ต้นไม้สีแดงดำทุกที่เมื่อพิจารณาจากสิ่งที่กล่าวข้างต้นต้นไม้ B ควรมีประสิทธิภาพสูงกว่าต้นไม้เหล่านั้นหรือไม่ (เป็นมาตรฐานเดียวที่ฉันสามารถค้นหาได้แสดงให้เห็นถึงhttp://lh3lh3.users.sourceforge.net/udb.shtmlแต่มันอาจเป็นเรื่องของการใช้งานเฉพาะ) หรือเป็นเหตุผลว่าทำไมทุกคนใช้ต้นไม้สีแดงดำเพราะมันค่อนข้างง่ายต่อการติดตั้งหรือใช้มันในคำที่แตกต่างกัน
นอกจากนี้การเปลี่ยนแปลงนี้จะเกิดขึ้นเมื่อเราย้ายไปยังขอบเขตของภาษาที่ใช้งานได้อย่างไร ดูเหมือนว่าทั้ง Clojure และ Scala ใช้Hash array ที่พยายามแมปซึ่ง Clojure ใช้ตัวประกอบสาขาที่ 32