ฉันสงสัยมากว่าทำไมความเสถียรหรือไม่สำคัญในการเรียงลำดับอัลกอริทึม
IBM (Insertion, Bubble, Merge)
ฉันสงสัยมากว่าทำไมความเสถียรหรือไม่สำคัญในการเรียงลำดับอัลกอริทึม
IBM (Insertion, Bubble, Merge)
คำตอบ:
อัลกอริธึมการเรียงลำดับกล่าวกันว่ามีเสถียรภาพหากวัตถุสองตัวที่มีคีย์เท่ากันปรากฏในลำดับเดียวกันในเอาต์พุตเรียงลำดับตามที่ปรากฏในอาร์เรย์อินพุตที่จะเรียงลำดับ อัลกอริทึมการเรียงลำดับบางอย่างมีความเสถียรตามธรรมชาติเช่นการเรียงลำดับการเรียงผสานผสานการเรียงลำดับฟอง ฯลฯ และอัลกอริทึมการเรียงลำดับบางอย่างไม่เหมือนกับการเรียงเรียงฮีปการเรียงลำดับด่วน ฯลฯ
พื้นหลัง : อัลกอริทึมการเรียงลำดับ "เสถียร" จะเก็บรายการต่างๆด้วยคีย์การเรียงลำดับเดียวกันตามลำดับ สมมติว่าเรามีรายการคำ 5 ตัวอักษร:
peach
straw
apple
spork
หากเราเรียงรายการตามตัวอักษรตัวแรกของแต่ละคำดังนั้นการเรียงแบบคงที่จะสร้าง:
apple
peach
straw
spork
ในความไม่แน่นอนขั้นตอนวิธีการเรียงลำดับstraw
หรือspork
อาจจะสบตา แต่ในเสถียรภาพหนึ่งที่พวกเขาอยู่ในตำแหน่งเดียวกันญาติ (นั่นคือตั้งแต่straw
ปรากฏขึ้นก่อนที่spork
ในการป้อนข้อมูลก็ยังปรากฏขึ้นก่อนที่spork
ในการส่งออก)
เราสามารถเรียงลำดับรายการคำโดยใช้อัลกอริธึมนี้: การเรียงแบบเสถียรตามคอลัมน์ 5 จากนั้น 4 จากนั้น 3 จากนั้น 2 จากนั้น 1 ในท้ายที่สุดมันจะถูกจัดเรียงอย่างถูกต้อง โน้มน้าวตัวเองจากสิ่งนั้น (โดยวิธีการอัลกอริทึมที่เรียกว่าการเรียงลำดับ Radix)
ตอนนี้เพื่อตอบคำถามของคุณสมมติว่าเรามีรายชื่อและนามสกุล เราถูกขอให้จัดเรียง "ตามนามสกุลจากนั้นตามด้วย" เราสามารถเรียงลำดับแรก (เสถียรหรือไม่เสถียร) โดยชื่อแรกแล้วเรียงลำดับเสถียรตามนามสกุล หลังจากเรียงลำดับเหล่านี้รายการจะถูกจัดเรียงตามนามสกุล อย่างไรก็ตามโดยที่นามสกุลเหมือนกันชื่อแรกจะถูกจัดเรียง
คุณไม่สามารถเรียงลำดับที่ไม่เสถียรในแบบเดียวกัน
straw
และspork
เปรียบเทียบกัน การเรียงลำดับที่เสถียรจะรักษาลำดับของอินพุตในขณะที่การเรียงลำดับที่ไม่เสถียรไม่รับประกัน "ถูกต้อง" ขึ้นอยู่กับแอปพลิเคชัน ฟังก์ชั่นการเรียงลำดับในภาษาการเขียนโปรแกรมส่วนใหญ่ช่วยให้ผู้ใช้จัดหาฟังก์ชั่นการสั่งซื้อที่กำหนดเอง หากฟังก์ชั่นของผู้ใช้มีรายการต่างกันเท่ากัน (เช่นชื่อเดียวกัน, นามสกุลต่างกัน) มันจะช่วยให้ทราบว่าคำสั่งซื้อเดิมจะถูกเก็บไว้หรือไม่ ดูฟังก์ชันการเรียงลำดับอาร์เรย์ของ OCamlสำหรับตัวอย่างจริง
อัลกอริธึมการเรียงลำดับที่เสถียรคือสิ่งที่เรียงลำดับองค์ประกอบที่เหมือนกันในลำดับเดียวกันตามที่ปรากฏในอินพุตในขณะที่การเรียงลำดับที่ไม่เสถียรอาจไม่ตรงกับกรณี - ผมขอขอบคุณอัลกอริทึมของฉันวิทยากร Didem Gozupek ที่จะได้ให้ความเข้าใจในขั้นตอนวิธีการ
อัลกอริทึมการเรียงลำดับที่เสถียร:
อัลกอริทึมการเรียงลำดับไม่เสถียร:
ความเสถียรในการเรียงลำดับหมายความว่าระเบียนที่มีคีย์เดียวกันจะเก็บลำดับที่สัมพันธ์กันไว้ก่อนและหลังการเรียงลำดับ
ดังนั้นความเสถียรจึงมีความสำคัญหากและหากปัญหาที่คุณกำลังแก้ไขอยู่นั้นจำเป็นต้องเก็บรักษาลำดับที่เกี่ยวข้องนั้นไว้
หากคุณไม่ต้องการความเสถียรคุณสามารถใช้อัลกอริทึมที่รวดเร็วและจิบหน่วยความจำจากไลบรารีเช่น heapsort หรือ quicksort และลืมมันไปเลย
หากคุณต้องการความมั่นคงมันซับซ้อนกว่า อัลกอริธึมที่เสถียรมีการใช้ CPU และ / หรือหน่วยความจำขนาดใหญ่สูงกว่าอัลกอริทึมที่ไม่เสถียร ดังนั้นเมื่อคุณมีชุดข้อมูลขนาดใหญ่คุณจะต้องเลือกระหว่างการเอาชนะซีพียูหรือหน่วยความจำ หากคุณถูก จำกัด ทั้ง CPU และหน่วยความจำคุณมีปัญหา อัลกอริธึมเสถียรที่ดีในการประนีประนอมคือการจัดเรียงต้นไม้แบบไบนารี บทความวิกิพีเดียมีง่ายน่าสงสาร c ++ ดำเนินการบนพื้นฐานของ STL
คุณสามารถสร้างอัลกอริทึมที่ไม่เสถียรให้เป็นเสถียรได้โดยเพิ่มหมายเลขบันทึกดั้งเดิมเป็นคีย์สุดท้ายสำหรับแต่ละระเบียน
ขึ้นอยู่กับสิ่งที่คุณทำ
ลองนึกภาพว่าคุณมีบันทึกบางคนที่มีชื่อและนามสกุล ก่อนอื่นคุณเรียงลำดับรายการตามชื่อ หากคุณเรียงลำดับรายการด้วยอัลกอริธึมที่เสถียรโดยใช้นามสกุลคุณจะมีรายการเรียงตามชื่อและนามสกุล
มีเหตุผลบางประการที่ทำให้เสถียรภาพมีความสำคัญ หนึ่งคือถ้าไม่จำเป็นต้องสลับสองรายการโดยการแลกเปลี่ยนคุณสามารถทำให้เกิดการปรับปรุงหน่วยความจำหน้าถูกทำเครื่องหมายสกปรกและจำเป็นต้องเขียนใหม่ลงในดิสก์ (หรือสื่อช้าอื่น)
อัลกอริธึมการเรียงลำดับกล่าวกันว่ามีเสถียรภาพหากวัตถุสองตัวที่มีคีย์เท่ากันปรากฏในลำดับเดียวกันในเอาต์พุตที่เรียงลำดับตามที่ปรากฏในอาร์เรย์ที่ไม่เรียงลำดับอินพุต อัลกอริทึมการเรียงลำดับบางอย่างมีความเสถียรตามธรรมชาติเช่นการเรียงลำดับการเรียงผสานผสานการเรียงลำดับฟอง ฯลฯ และอัลกอริทึมการเรียงลำดับบางอย่างไม่เหมือนกับการเรียงเรียงฮีปการเรียงลำดับด่วน ฯลฯ
อย่างไรก็ตามอัลโกการเรียงลำดับที่กำหนดใด ๆ ที่ไม่เสถียรสามารถแก้ไขได้เพื่อให้มีเสถียรภาพ สามารถจัดเรียงอัลโกวิธีที่เฉพาะเจาะจงเพื่อให้มีเสถียรภาพ แต่โดยทั่วไปอัลกอริทึมการเรียงลำดับตามการเปรียบเทียบใด ๆ ที่ไม่เสถียรโดยธรรมชาติสามารถปรับเปลี่ยนให้เสถียรโดยการเปลี่ยนการดำเนินการเปรียบเทียบคีย์เพื่อให้การเปรียบเทียบของสองคีย์พิจารณาตำแหน่งเป็น ตัวคูณสำหรับวัตถุที่มีคีย์เท่ากัน
ข้อมูลอ้างอิง: http://www.math.uic.edu/~leon/cs-mcs401-s08/handouts/stability.pdf http://en.wikipedia.org/wiki/Sorting_algorithm#Stability
ฉันรู้ว่ามีคำตอบมากมายสำหรับเรื่องนี้ แต่สำหรับฉันคำตอบนี้โดยRobert Harveyสรุปได้ชัดเจนยิ่งขึ้น:
การเรียงแบบเสถียรนั้นเป็นสิ่งที่รักษาลำดับเดิมของชุดอินพุตซึ่งอัลกอริทึม [ไม่เสถียร] ไม่แยกความแตกต่างระหว่างสองรายการหรือมากกว่า
หากคุณถือว่าสิ่งที่คุณกำลังเรียงลำดับนั้นเป็นเพียงตัวเลขและมีเพียงค่าของพวกเขาที่ระบุ / แยกพวกมัน (เช่นองค์ประกอบที่มีค่าเดียวกันคือตัวระบุ) ดังนั้นปัญหาความมั่นคงของการเรียงลำดับจึงไม่มีความหมาย
อย่างไรก็ตามวัตถุที่มีลำดับความสำคัญเท่ากันในการเรียงลำดับอาจแตกต่างกันและบางครั้งลำดับญาติของพวกเขาคือข้อมูลที่มีความหมาย ในกรณีนี้การเรียงลำดับที่ไม่เสถียรสร้างปัญหา
ตัวอย่างเช่นคุณมีรายการของข้อมูลที่มีค่าใช้จ่ายเวลา [T] ของผู้เล่นทุกคนในการทำความสะอาดเขาวงกตด้วยระดับ [L] ในเกม สมมติว่าเราต้องจัดอันดับผู้เล่นด้วยความเร็วที่พวกเขาทำความสะอาดเขาวงกต อย่างไรก็ตามกฎเพิ่มเติมมีผลบังคับใช้: ผู้เล่นที่ทำความสะอาดเขาวงกตด้วยระดับที่สูงกว่าจะมีอันดับที่สูงกว่าเสมอไม่ว่าจะใช้เวลานานเท่าใด
แน่นอนคุณอาจลองแมปค่าที่จับคู่ [T, L] เป็นจำนวนจริง [R] ด้วยอัลกอริทึมบางตัวซึ่งปฏิบัติตามกฎแล้วจัดอันดับผู้เล่นทั้งหมดด้วยค่า [R]
อย่างไรก็ตามหากการเรียงลำดับที่เสถียรเป็นไปได้คุณสามารถเรียงลำดับรายการทั้งหมดด้วย [T] (ผู้เล่นที่เร็วกว่าก่อน) แล้วตามด้วย [L] ในกรณีนี้ลำดับสัมพัทธ์ของผู้เล่น (ตามเวลา) จะไม่เปลี่ยนแปลงหลังจากที่คุณจัดกลุ่มตามระดับของเขาวงกตที่พวกเขาทำความสะอาด
PS: แน่นอนว่าวิธีการเรียงสองครั้งนั้นไม่ใช่ทางออกที่ดีที่สุดสำหรับปัญหาเฉพาะ แต่เพื่ออธิบายคำถามของโปสเตอร์มันน่าจะเพียงพอแล้ว
การเรียงลำดับที่เสถียรจะส่งคืนโซลูชันเดียวกัน (การเปลี่ยนแปลง) ในอินพุตเดียวกันเสมอ
ตัวอย่างเช่น [2,1,2] จะถูกจัดเรียงโดยใช้การเรียงแบบคงที่เป็นการเรียงสับเปลี่ยน [2,1,3] (แรกคือดัชนี 2 จากนั้นดัชนี 1 จากนั้นดัชนี 1 จากดัชนีเรียงลำดับผลลัพธ์) นั่นหมายความว่าเอาต์พุตจะสับแบบเดียวกันเสมอ อื่น ๆ ไม่เสถียร แต่ยังคงการเปลี่ยนแปลงที่ถูกต้องคือ [2,3,1]
การจัดเรียงอย่างรวดเร็วไม่ได้เป็นการเรียงที่เสถียรและความแตกต่างของการเปลี่ยนแปลงในองค์ประกอบเดียวกันนั้นขึ้นอยู่กับอัลกอริทึมสำหรับการเลือกเดือย การใช้งานบางอย่างสุ่มขึ้นมาและสามารถทำการเรียงลำดับอย่างรวดเร็วให้การเรียงสับเปลี่ยนที่แตกต่างกันในอินพุตเดียวกันโดยใช้อัลกอริทึมเดียวกัน
อัลกอริทึมการเรียงลำดับที่เสถียรเป็นสิ่งที่จำเป็นอย่างยิ่ง
sort([(5,3),(1,5),(3,3),(1,3)], x) => [(1,5),(1,3),(3,3),(5,3)]
ตัวอย่างของผลลัพธ์ของการจัดเรียงที่มีเสถียรภาพ: ฉันสามารถสร้างการจัดเรียงที่กำหนดไว้ซึ่งผลลัพธ์ (กำหนดขึ้นได้) เสมอ: [(1,3),(1,5),(3,3),(5,3)]
แต่นี่ไม่ใช่การจัดเรียงที่มีเสถียรภาพ
ตัวอย่างเพิ่มเติมของเหตุผลที่ต้องการเรียงลำดับที่มั่นคง ฐานข้อมูลเป็นตัวอย่างทั่วไป ใช้กรณีของฐานข้อมูลการทำธุรกรรมมากกว่ารวมถึง | ชื่อ, วันที่ | เวลาที่ซื้อ, จำนวนรายการ, ราคา สมมติว่าฐานข้อมูลปกติเรียงตามวันที่ | เวลา จากนั้นแบบสอบถามจะสร้างสำเนาที่เรียงลำดับของฐานข้อมูลด้วยนามสกุล | เนื่องจากการเรียงที่เสถียรจะรักษาลำดับเดิมไว้แม้ว่าการสอบถามเปรียบเทียบจะเกี่ยวข้องเฉพาะกับนามสกุล | ชื่อธุรกรรมสำหรับแต่ละนามสกุลจะเป็น อยู่ในข้อมูล | เวลาสั่ง
ตัวอย่างที่คล้ายกันคือ Excel แบบคลาสสิกซึ่ง จำกัด เรียงลำดับไว้ที่ 3 คอลัมน์ต่อครั้ง ในการจัดเรียง 6 คอลัมน์การเรียงลำดับจะดำเนินการด้วย 3 คอลัมน์ที่มีความสำคัญน้อยที่สุดตามด้วยการเรียงลำดับที่มีคอลัมน์ที่สำคัญที่สุด 3 คอลัมน์
ตัวอย่างคลาสสิกของการจัดเรียง radix ที่เสถียรคือตัวเรียงลำดับการ์ดที่ใช้เรียงลำดับตามเขตข้อมูลของคอลัมน์ฐาน 10 คอลัมน์ บัตรจะถูกจัดเรียงจากตัวเลขที่มีนัยสำคัญน้อยที่สุดไปเป็นจำนวนที่สำคัญที่สุด ในแต่ละรอบไพ่จะถูกอ่านและแยกออกเป็น 10 ถังที่แตกต่างกันตามตัวเลขในคอลัมน์นั้น จากนั้นการ์ด 10 ช่องจะถูกใส่กลับเข้าไปในช่องป้อนข้อมูลตามลำดับ ("การ์ด" 0 ใบแรก, การ์ด "9" ครั้งสุดท้าย) จากนั้นจะมีการส่งอีกรอบโดยคอลัมน์ถัดไปจนกว่าคอลัมน์ทั้งหมดจะถูกจัดเรียง ตัวเรียงลำดับบัตรจริงมีช่องเก็บมากกว่า 10 ช่องเนื่องจากมี 12 โซนบนการ์ดคอลัมน์สามารถเว้นว่างได้และมีช่องอ่านผิด ในการจัดเรียงตัวอักษรจำเป็นต้องใช้ 2 รอบต่อคอลัมน์, รอบที่ 1 สำหรับหลัก, รอบสองสำหรับ 12 11 โซน
ต่อมา (1937) มีการเรียงบัตร (รวม) เครื่องที่สามารถรวมสองชั้นของไพ่โดยการเปรียบเทียบเขตข้อมูล อินพุตเป็นไพ่สองสำรับที่ได้เรียงลำดับแล้วไพ่สำรับหลักและสำรับอัปเดต Collator ได้รวมสองเด็คเข้ากับ aa mater bin ใหม่และ bin ที่เก็บถาวรซึ่งใช้เป็นทางเลือกสำหรับการทำสำเนาข้อมูลหลักเพื่อให้ master bin ใหม่จะมีการอัพเดตการ์ดในกรณีที่ซ้ำกันเท่านั้น นี่อาจเป็นพื้นฐานสำหรับแนวคิดที่อยู่เบื้องหลังการเรียงลำดับการผสานแบบดั้งเดิม (ล่างขึ้นบน)