โดยทั่วไปแล้วฉันจะใช้ Deque ในซอฟต์แวร์การผลิตที่ไหน


21

ฉันค่อนข้างคุ้นเคยกับการใช้สแต็คคิวและต้นไม้ในแอปพลิเคชันซอฟต์แวร์ แต่ฉันไม่เคยใช้ Deque (Double Ended Queue) มาก่อน โดยทั่วไปแล้วฉันจะพบพวกเขาที่ไหนในป่า? มันจะอยู่ในสถานที่เดียวกันกับคิว แต่มี gribbilies พิเศษหรือไม่?



ดูเหมือนว่ามีความสับสนในหัวข้อนี้ บนอินเทอร์เน็ต "deque" เป็นคิวสองครั้ง (วิกิพีเดียกล่าวถึงการเชื่อมโยงการใช้งานรายการ) อย่างไรก็ตามใน C ++ STL "std :: deque" เป็นโครงสร้างแบบ array ที่นำมาใช้เป็นอาร์เรย์ของ data block มันมีการเข้าถึงแบบสุ่มคล้ายกับ std :: vector แต่ความสามารถในการปรับขนาดของมันใกล้เคียงกับ std :: list เพราะเมื่อมีการเพิ่มข้อมูลมันจะเพิ่มบล็อกและไม่ได้จัดสรรใหม่และย้ายข้อมูลที่มีอยู่
DXM

1
@DXM: STL deque ยังคงเป็นคิวดับเบิลสิ้นสุดแม้ว่าและให้การดำเนินการที่รวดเร็วกว่าในตอนท้าย (ขึ้นอยู่กับการใช้งาน) ที่ให้การเข้าถึงกลางเช่นกันไม่ได้ทำให้การดำเนินงานหลักของมันน้อยลงเช่นคิว
gbjbaanb

@gbjbaanb: ทั้งหมดที่ฉันพูดคือถ้าคุณดูอินเทอร์เฟซสาธารณะของ 3 คลาส: std :: vector, std :: list (หรือ std :: queue) และ std :: deque, คุณจะเห็น std :: vector และ std :: deque มีส่วนต่อประสานสาธารณะที่เหมือนกันและความสามารถที่เหมือนกัน (std :: deque มีความยืดหยุ่นมากขึ้นเล็กน้อยโดยเสียค่าใช้จ่ายจากหน่วยความจำขนาดใหญ่กว่า) std :: list และ std :: queue ในทางกลับกันมีพฤติกรรมเหมือน CS counter-parts, linked-list และ queue ตามลำดับ CS deque! = std :: deque
DXM

ฉันพบว่าคำตอบนี้ใช้งานได้จริงโดย shiv.mymail - stackoverflow.com/questions/3880254/…
roottraveller

คำตอบ:


21

วิธีหนึ่งที่ใช้ deque คือรายการ "อายุ" โดยทั่วไปจะใช้เป็นคุณสมบัติการเลิกทำหรือประวัติ การกระทำใหม่จะถูกแทรกลงใน deque รายการที่เก่าแก่ที่สุดอยู่ที่ด้านหน้า ข้อ จำกัด เกี่ยวกับขนาดของ deque บังคับให้ไอเท็มด้านหน้าถูกลบในบางจุดเมื่อไอเท็มใหม่ถูกแทรก จากนั้นให้วิธีที่รวดเร็วในการเข้าถึงทั้งสองด้านของโครงสร้างเพราะคุณจะรู้ว่ารายการที่เก่าแก่ที่สุดและใหม่ล่าสุดทันทีเพื่อลบด้านหน้าและกระทำสิ่งที่เก่าที่สุดใน O (1) หรือเลิกทำในเวลา O (1)


ฉันไม่คิดว่ามีการใช้งาน deques / จำเป็นที่นี่ สแต็กที่เรียบง่าย (อาจ จำกัด ขนาด) ก็เพียงพอแล้ว
Konrad Rudolph

2
@Konrad คุณอายุรายการในกองง่าย ๆ ได้อย่างไร (เช่นคุณจะลบคำสั่งที่เก่าเกินไปอย่างไร?)
Andres F.

@AndresF อายุไม่ขึ้นกับขนาดสแต็กหรือไม่ ถ้าเป็นเช่นนั้นฉันไม่เคยได้ยินโครงสร้างข้อมูลนี้เลย มิฉะนั้นเป็นเพียงสแต็กที่มีขนาดคงที่ซึ่งสามารถนำไปใช้ในรูปแบบของ deque หรือเพียงโดยการวางโครงสร้างข้อมูลที่ง่ายกว่าที่เรียกว่าสแต็กขนาดคงที่
Konrad Rudolph

ดังนั้น deques มีประโยชน์หลังจากทั้งหมด;) ไม่เคยได้ยินเกี่ยวกับกองซ้อนขนาดคงที่ (ในแง่ที่คุณหมายถึงการลบรายการที่เก่าที่สุด) มันสมเหตุสมผล แต่มันไม่ใช่สิ่งที่มักจะหมายถึง "stack" และไม่ว่าจะเป็นเรื่องง่ายกว่าที่จะเห็น :)
Andres F.

สิ่งนี้ถูกโพสต์ในความคิดเห็นของคำถามเดิม: en.wikipedia.org/wiki/Double-ended_queueมันเป็นแค่คิวที่ลงท้ายด้วยคู่ ฉันได้ใช้มันในทางปฏิบัติตามที่ระบุไว้ข้างต้น (ซึ่งเป็นสาเหตุที่ฉันโพสต์ไว้) ในสแต็กจริงการดำเนินการเดียวที่คุณควรมีคือ push, pop, top และ peek (เราสามารถโต้เถียงผู้อื่นได้ คุณไม่ควรรู้สิ่งที่อยู่ด้านล่างของสแต็กหรือแม้แต่วิธีเข้าถึงด้านล่าง ใน "สแต็กขนาดคงที่" คุณจะสร้างสแต็คโอเวอร์โฟลว์แทนรายการเก่าที่มีอายุมากขึ้น
jmq

1

คำถามที่ยอดเยี่ยม ฉันจำหลักสูตร CS 102 ของเราไม่ได้โดยพูดถึงแอปพลิเคชั่นเดียวสำหรับคิวแบบสองครั้งสุดท้าย

จนถึงวันนี้โปรแกรมเดียวที่ฉันรู้คือกำหนดการทำงานขโมยกล่าวถึงในบทความวิกิพีเดีย

มันทำงานเป็นหลักดังนี้

ในความปกติรูปแบบขั้นตอนเดียว threaded ทุกฟังก์ชั่นการโทรผลักดันบันทึกยืนยันการใช้งานในสิ่งที่เรียกว่าสแต็คโทร เร็กคอร์ดการเปิดใช้งานมีตัวแปรท้องถิ่นและพารามิเตอร์ของการโทรนั้น เมื่อการเรียกใช้เมธอดเสร็จสมบูรณ์ (“ คืนค่า”) เรคคอร์ดการเปิดใช้งานล่าสุดจะถูกเปิดจากสแต็คการโทร

สิ่งนี้มีความสำคัญอย่างยิ่งเนื่องจากเป็นวิธีการเรียกใช้ซ้ำ: โครงสร้างของการเรียกซ้ำถูกแสดงในสถานะปัจจุบันของ call stack

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

แต่เมื่อด้ายได้เสร็จสิ้นการทำงานของมัน (= คิวเรียกเป็นที่ว่างเปล่า) ก็ขโมยทำงานจากหัวข้ออื่นโดยการลบบันทึกการเปิดใช้งานจากคิวโทรหัวข้อที่โดยการเอาจาก“ผิด” ในตอนท้าย

โดยทั่วไปคิวการโทรทำหน้าที่เป็นสองกองการโทรซึ่งตอนนี้ทำหน้าที่สองหัวข้อ


คุณมีแหล่งที่มาสำหรับสิ่งนี้หรือไม่? ฟังดูน่าสนใจ.
kyjelly90210

1
@ Richard1987 บทความ Wikipedia อ้างอิงเอกสารต้นฉบับ มีการใช้งานหลายอย่างเช่นในGNU c ++ stdlib ส่วนขยายแบบขนานการประยุกต์ใช้งานขโมย (แต่โค้ดน่ากลัวมากที่จะอ่าน) หรือการใช้งานแบบขนานของการหาร & พิชิตโดยทั่วไปของคุณอย่างแท้จริง (แต่หลังใช้สไตล์การเขียนโปรแกรม โดยเฉพาะอย่างยิ่งกับห้องสมุดและทำให้อ่านยาก)
Konrad Rudolph
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.