ขั้นตอน "หาร" ในการเรียงแบบผสานสามารถหลีกเลี่ยงได้หรือไม่


13

เรียงลำดับการผสาน

การเรียงลำดับผสานจึงเป็นอัลกอริธึมการแบ่งและพิชิต ขณะที่ฉันดูแผนภาพข้างต้นฉันคิดว่าถ้าเป็นไปได้ที่จะข้ามขั้นตอนหารทั้งหมด

หากคุณวนซ้ำอาร์เรย์เดิมในขณะที่กระโดดสองครั้งคุณจะได้รับองค์ประกอบที่ index i และ i + 1 และใส่เข้าไปในอาร์เรย์ที่เรียงลำดับของตัวเอง เมื่อคุณมีอาร์เรย์ย่อยทั้งหมดเหล่านี้ ([7,14], [3,12], [9,11] และ [2,6] ดังที่แสดงในแผนภาพ) คุณสามารถดำเนินการตามปกติตามปกติเพื่อรับ อาร์เรย์ที่เรียงลำดับ

วนซ้ำผ่านอาร์เรย์และสร้างอาร์เรย์ย่อยที่จำเป็นในทันทีมีประสิทธิภาพน้อยกว่าการดำเนินการตามขั้นตอนหารอย่างครบถ้วนหรือไม่


ที่เกี่ยวข้อง: cs.stackexchange.com/questions/77075/…
โอมาร์

คำตอบ:


29

ความสับสนที่เกิดจากความแตกต่างระหว่างความคิดรายละเอียดของขั้นตอนวิธีการและการดำเนินงาน

การเรียงลำดับการผสานแบบโลจิคัลมีการอธิบายเป็นการแยกอาร์เรย์ออกเป็นอาร์เรย์ขนาดเล็กแล้วผสานกลับเข้าด้วยกัน อย่างไรก็ตาม "การแบ่งอาร์เรย์" ไม่ได้หมายความว่า "การสร้างอาร์เรย์ใหม่ทั้งหมดในหน่วยความจำ" หรืออะไรทำนองนั้น - มันสามารถนำไปใช้ในรหัสเป็น

/*
 * Note: array is now split into  [0..n) and [n..N)
 */

เช่นไม่มีงานจริงเกิดขึ้นและ "การแยก" เป็นแนวคิดอย่างหมดจด ดังนั้นสิ่งที่คุณแนะนำจะทำงานได้อย่างแน่นอน แต่ตามหลักเหตุผลคุณยังคง "แยก" อาร์เรย์ - คุณเพียงแค่ไม่ต้องการงานใด ๆ จากคอมพิวเตอร์เพื่อ :-)


4
โดยส่วนตัวฉันชอบเรียงลำดับจากล่างขึ้นบนเพราะมันง่ายกว่าที่จะนำไปใช้ในวิธีที่ช่วยให้คุณหลีกเลี่ยงการจัดสรรบัฟเฟอร์ชั่วคราวในแต่ละระดับการสอบถามซ้ำ แต่คุณจัดสรรบัฟเฟอร์หนึ่งครั้งและปิงปองระหว่างพวกเขา
วงล้อประหลาด

นี่ - การหารเป็นการคำนวณแบบไม่ใช้คำสั่ง ... และคำแนะนำ OPs เป็นเพียงการแนะนำการเทียบเท่ากับการรวมกันของอาร์เรย์องค์ประกอบเดียวและเริ่มใช้การผสานจากขั้นตอนที่ 2 ซึ่งดูเหมือนว่าซ้ำซ้อนเพราะการผสานดั้งเดิมทำงานได้ดีเช่นกัน ไม่มีประเด็นในการปรับให้เหมาะสม มันแนะนำแนวคิดและตรรกะที่ซ้ำซ้อนเท่านั้น
luk32

@ ratchetfreak: ฉันก็ชอบเหมือนกัน แต่น่าเศร้าที่มันไม่เทียบเท่ากับการเลื่อนจากบนลงล่าง (อย่างน้อยฉันก็รู้จัก มันจะทำการควบรวมที่แตกต่างกันโดยทั่วไปจะปัดเศษขึ้นเป็นความยาวอาเรย์ของ 2 อันถัดไปซึ่งฉันคิดว่าอาจช้าลงเล็กน้อย คุณรู้จักรุ่นจากล่างขึ้นบนที่ทำการผสานแบบเดียวกันโดยไม่ต้องเสียค่าใช้จ่ายจำนวนมากใช่ไหม?
user541686

@Mehrdad ปัญหาเฉพาะที่แท้จริงคือหางเล็ก ๆ น้อย ๆ ที่จะต้องรวมอยู่ใน. 1<<n+1ในกรณีที่เลวร้ายที่สุดนั่นหมายความว่าผ่านอีกครั้งเพื่อให้ผสานในรายการเดียวสำหรับอาร์เรย์ของความยาว แม้ว่าฉันจะแน่ใจว่าคุณสามารถปรับเปลี่ยนสิ่งต่าง ๆ ได้ดังนั้นหางขนาดเล็กเกินไปจึงถูกรวมเข้าด้วยกันในระดับล่าง
วงล้อประหลาด

@psmears "คุณแค่ไม่ต้องการงานจากคอมพิวเตอร์" - ดังนั้นฉันเดาว่าค่าใช้จ่ายในการโทรnสายของฟังก์ชั่นการหารซ้ำ (7 สายในแผนภาพตัวอย่าง) นั้นเล็กน้อย
Jimmy_Rustle

11

ฉันเดาว่าคุณหมายถึงอะไรคือการนำไปใช้จากล่างขึ้นบน ในการใช้งานด้านล่างขึ้นบนคุณเริ่มต้นจากองค์ประกอบเซลล์เดียวย้ายขึ้นไปโดยการรวมองค์ประกอบเป็นรายการ / อาร์เรย์เรียงลำดับขนาดใหญ่ เพียงย้อนกลับลูกศรในรูปของคุณด้านบนเริ่มต้นจากอาร์เรย์กลางเช่นอาร์เรย์หนึ่งองค์ประกอบ

นอกจากนี้คุณอาจต้องการเพิ่มประสิทธิภาพการเรียงลำดับการผสานโดยการหารอาร์เรย์จนกว่าจะถึงขนาดคงที่บางส่วนหลังจากนั้นคุณก็เรียงลำดับการใช้ตัวอย่างเช่นการเรียงลำดับการแทรก

ไม่เช่นนั้นการเรียงลำดับโดยไม่ต้องใช้อาเรย์แยก ในความเป็นจริงส่วนสำคัญของการจัดเรียงผสานคือการแบ่งและการเรียงลำดับ subarrays เช่นหารและพิชิต

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.