มันสมเหตุสมผลสำหรับฉันว่าสิ่งนี้ทำให้การแก้ไขปัญหาได้เร็วขึ้นหากทั้งสองส่วนใช้เวลาน้อยกว่าครึ่งในการจัดการกับชุดข้อมูลทั้งหมด
นั่นไม่ใช่สาระสำคัญของอัลกอริธึมหารและพิชิต โดยทั่วไปประเด็นคืออัลกอริธึมไม่สามารถ "จัดการกับชุดข้อมูลทั้งหมด" ได้เลย แต่จะแบ่งออกเป็นชิ้นเล็ก ๆ น้อย ๆ ที่จะแก้ปัญหา (เช่นการเรียงลำดับตัวเลขสองจำนวน) จากนั้นจะถูกแก้ไขเล็กน้อยและผลลัพธ์จะรวมกันอีกครั้งในลักษณะที่ให้วิธีการแก้ปัญหาสำหรับชุดข้อมูลแบบเต็ม
แต่ทำไมไม่แยกชุดข้อมูลออกเป็นสามส่วน? สี่? n?
สาเหตุหลักมาจากการแยกออกเป็นสองส่วนและรวบรวมผลลัพธ์มากกว่าสองรายการส่งผลให้เกิดการใช้งานที่ซับซ้อนมากขึ้น แต่ไม่ได้เปลี่ยนลักษณะพื้นฐาน (Big O) ของอัลกอริทึม - ความแตกต่างเป็นปัจจัยคงที่และอาจส่งผลให้การชะลอตัว ถ้าการหารและการรวมเข้าด้วยกันอีกครั้งของ 2 เซ็ตย่อยสร้างค่าใช้จ่ายเพิ่มเติม
ตัวอย่างเช่นหากคุณทำการเรียงแบบผสาน 3 ทางจากนั้นในขั้นตอนการรวมตัวกันใหม่ตอนนี้คุณต้องค้นหาองค์ประกอบที่ใหญ่ที่สุดของ 3 องค์ประกอบสำหรับทุกองค์ประกอบซึ่งต้องใช้การเปรียบเทียบ 2 แทนที่จะเป็น 1 ดังนั้นคุณจะทำการเปรียบเทียบสองเท่า . ในการแลกเปลี่ยนคุณลดความลึกของการเรียกซ้ำโดยใช้ ln (2) / ln (3) == 0.63 ดังนั้นคุณจึงมีการแลกเปลี่ยนน้อยลง 37% แต่ 2 * 0.63 == การเปรียบเทียบเพิ่มเติม 26% (และการเข้าถึงหน่วยความจำ) ไม่ว่าจะดีหรือไม่ดีขึ้นอยู่กับว่าฮาร์ดแวร์ของคุณมีราคาแพงกว่าหรือไม่
ฉันยังได้เห็นการอ้างอิงจำนวนมากถึง QuickSort 3 ทาง เมื่อไหร่จะเร็วกว่านี้?
เห็นได้ชัดว่าตัวแปรเดือยคู่ของ quicksortสามารถพิสูจน์ได้ว่าต้องการการเปรียบเทียบจำนวนเท่ากัน แต่โดยเฉลี่ยน้อยกว่า 20% swaps ดังนั้นจึงเป็นกำไรสุทธิ
สิ่งที่ใช้ในการปฏิบัติ?
ทุกวันนี้แทบจะไม่มีใครเขียนโปรแกรมอัลกอริธึมการเรียงลำดับของตัวเองอีกต่อไป พวกเขาใช้อย่างใดอย่างหนึ่งโดยห้องสมุด ตัวอย่างเช่นJava 7 APIจริง ๆ แล้วใช้ dual-pivot quicksort
คนที่ตั้งโปรแกรมอัลกอริทึมการเรียงลำดับของตัวเองด้วยเหตุผลบางอย่างจะมีแนวโน้มที่จะยึดติดกับตัวแปรสองทางแบบง่าย ๆ เพราะโอกาสที่จะเกิดข้อผิดพลาดน้อยกว่านั้นจะทำให้ประสิทธิภาพดีขึ้น 20% เป็นส่วนใหญ่ โปรดจำไว้ว่า: การปรับปรุงประสิทธิภาพที่สำคัญที่สุดคือเมื่อรหัสเปลี่ยนจาก "ไม่ทำงาน" เป็น "กำลังทำงาน"