มีแนวโน้มสูงจาก Josh Bloch § :
ฉันเขียนวิธีการเหล่านี้ดังนั้นฉันคิดว่าฉันมีคุณสมบัติที่จะตอบ เป็นความจริงที่ว่าไม่มีอัลกอริทึมการเรียงลำดับที่ดีที่สุดเพียงวิธีเดียว QuickSort มีข้อบกพร่องที่สำคัญสองประการเมื่อเปรียบเทียบกับการผสาน:
มันไม่คงที่ (ตามที่ parsifal ระบุไว้)
ไม่รับประกันประสิทธิภาพ n log n; สามารถลดประสิทธิภาพเป็นกำลังสองของปัจจัยทางพยาธิวิทยา
ความเสถียรไม่ใช่ปัญหาสำหรับประเภทดั้งเดิมเนื่องจากไม่มีแนวคิดเรื่องอัตลักษณ์ที่แตกต่างจากความเท่าเทียมกัน (ค่า) และความเป็นไปได้ของพฤติกรรมกำลังสองถือว่าไม่เป็นปัญหาในทางปฏิบัติสำหรับการใช้งานของ Bentely และ McIlroy (หรือต่อมาสำหรับDual Pivot Quicksort ) ซึ่งเป็นสาเหตุที่ตัวแปร QuickSort เหล่านี้ใช้สำหรับประเภทดั้งเดิม
ความเสถียรเป็นเรื่องใหญ่เมื่อจัดเรียงวัตถุโดยพลการ ตัวอย่างเช่นสมมติว่าคุณมีวัตถุที่เป็นตัวแทนของข้อความอีเมลและคุณเรียงลำดับตามวันที่ก่อนแล้วตามผู้ส่ง คุณคาดว่าจะจัดเรียงตามวันที่ภายในผู้ส่งแต่ละราย แต่จะเป็นจริงก็ต่อเมื่อการจัดเรียงมีเสถียรภาพ นั่นเป็นเหตุผลที่เราเลือกที่จะจัดเรียงแบบคงที่ (Merge Sort) เพื่อจัดเรียงการอ้างอิงวัตถุ (ในทางเทคนิคการเรียงลำดับที่มีเสถียรภาพตามลำดับหลายรายการส่งผลให้มีการเรียงลำดับคำศัพท์บนคีย์ในลำดับย้อนกลับของประเภท: การเรียงลำดับสุดท้ายจะกำหนดคีย์ย่อยที่สำคัญที่สุด)
เป็นข้อดีที่ Merge Sort รับประกันประสิทธิภาพ n log n (เวลา) ไม่ว่าจะป้อนข้อมูลใดก็ตาม แน่นอนว่ามีข้อเสียอยู่: การเรียงลำดับอย่างรวดเร็วคือการจัดเรียงแบบ "ในสถานที่": มันต้องการเฉพาะบันทึก n พื้นที่ภายนอก (เพื่อรักษา call stack) ในทางกลับกันการผสานการจัดเรียงต้องใช้พื้นที่ภายนอก O (n) ตัวแปร TimSort (แนะนำใน Java SE 6) ต้องการพื้นที่น้อยลงอย่างมาก (O (k)) หากอาร์เรย์อินพุตเกือบจะเรียงลำดับ
นอกจากนี้สิ่งต่อไปนี้เกี่ยวข้อง:
อัลกอริทึมที่ใช้โดย java.util.Arrays.sort และ (ทางอ้อม) โดย java.util.Collections.sort เพื่อเรียงลำดับการอ้างอิงอ็อบเจ็กต์คือ "modified mergesort (ซึ่งการผสานจะถูกละไว้หากองค์ประกอบสูงสุดในรายการย่อยต่ำมีค่าน้อยกว่า องค์ประกอบที่ต่ำที่สุดในรายการย่อยระดับสูง) " เป็นการเรียงลำดับที่เสถียรอย่างรวดเร็วพอสมควรซึ่งรับประกันประสิทธิภาพ O (n log n) และต้องการพื้นที่พิเศษ O (n) ในสมัยนั้น (เขียนในปี 1997 โดย Joshua Bloch) มันเป็นทางเลือกที่ดี แต่วันนี้เราทำได้ดีกว่ามาก
ตั้งแต่ปี 2546 การจัดเรียงรายการของ Python ได้ใช้อัลกอริทึมที่เรียกว่า timsort (หลังจาก Tim Peters ผู้เขียน) เป็นการผสานที่เสถียรปรับตัวได้และทำซ้ำซึ่งต้องการการเปรียบเทียบน้อยกว่า n log (n) มากเมื่อทำงานบนอาร์เรย์ที่เรียงลำดับบางส่วนในขณะที่ให้ประสิทธิภาพเทียบเท่ากับการผสานแบบดั้งเดิมเมื่อรันบนอาร์เรย์แบบสุ่ม เช่นเดียวกับ timsort การผสานที่เหมาะสมทั้งหมดมีเสถียรภาพและทำงานในเวลา O (n log n) (กรณีที่เลวร้ายที่สุด) ในกรณีที่แย่ที่สุด timsort ต้องการพื้นที่จัดเก็บชั่วคราวสำหรับการอ้างอิงอ็อบเจ็กต์ n / 2 ในกรณีที่ดีที่สุดต้องใช้พื้นที่คงที่เพียงเล็กน้อย ตรงกันข้ามกับการใช้งานปัจจุบันซึ่งต้องใช้พื้นที่พิเศษสำหรับการอ้างอิงอ็อบเจ็กต์ n เสมอและเต้น n log n เฉพาะในรายการที่เรียงลำดับเกือบเท่านั้น
Timsort อธิบายไว้ในรายละเอียดที่นี่:
http://svn.python.org/projects/python/trunk/Objects/listsort.txt
การนำไปใช้งานดั้งเดิมของ Tim Peters เขียนด้วยภาษา C Joshua Bloch ได้ย้ายจาก C ไปยัง Java และสิ้นสุดการทดสอบเปรียบเทียบและปรับแต่งโค้ดผลลัพธ์อย่างครอบคลุม โค้ดผลลัพธ์คือการแทนที่แบบดรอปอินสำหรับ java.util.Arrays.sort ในข้อมูลที่มีลำดับสูงรหัสนี้สามารถทำงานได้เร็วกว่าการใช้งานปัจจุบันถึง 25 เท่า (บนเซิร์ฟเวอร์ HotSpot VM) ในข้อมูลแบบสุ่มความเร็วของการใช้งานเก่าและใหม่จะเทียบเคียง สำหรับรายการที่สั้นมากการใช้งานใหม่จะเร็วกว่าอย่างมากแม้ว่าข้อมูลเก่าจะเป็นแบบสุ่ม (เนื่องจากหลีกเลี่ยงการคัดลอกข้อมูลที่ไม่จำเป็น)
นอกจากนี้โปรดดูที่Java 7 ใช้ Tim Sort สำหรับ Method Arrays.Sort หรือไม่ .
ไม่มีทางเลือกเดียวที่ "ดีที่สุด" เช่นเดียวกับสิ่งอื่น ๆ อีกมากมายมันเกี่ยวกับการแลกเปลี่ยน