เหตุใด std :: stack จึงใช้ std :: deque ตามค่าเริ่มต้น


91

เนื่องจากการดำเนินการเดียวที่จำเป็นสำหรับคอนเทนเนอร์ที่จะใช้ในสแต็กคือ:

  • กลับ()
  • push_back ()
  • pop_back ()

เหตุใดคอนเทนเนอร์เริ่มต้นจึงเป็น deque แทนที่จะเป็นเวกเตอร์

อย่าถอดการจัดสรรใหม่ให้บัฟเฟอร์ขององค์ประกอบก่อน front () เพื่อให้ push_front () เป็นการดำเนินการที่มีประสิทธิภาพ? องค์ประกอบเหล่านี้ไม่สูญเปล่าเนื่องจากจะไม่ถูกใช้ในบริบทของสแต็ก?

หากไม่มีค่าใช้จ่ายสำหรับการใช้ deque ด้วยวิธีนี้แทนเวกเตอร์เหตุใดค่าเริ่มต้นสำหรับ priority_queue จึงเป็นเวกเตอร์จึงไม่ใช่ deque ด้วย (Priority_queue ต้องการ front (), push_back () และ pop_back () - โดยพื้นฐานแล้วเหมือนกับ stack)


อัปเดตตามคำตอบด้านล่าง:

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

priority_queue ต้องการการจัดทำดัชนีอย่างมากเนื่องจากการลบและการแทรกทุกครั้งทำให้คุณต้องเรียกใช้ pop_heap () หรือ push_heap () สิ่งนี้อาจทำให้เวกเตอร์เป็นทางเลือกที่ดีกว่าเนื่องจากการเพิ่มองค์ประกอบยังคงถูกตัดจำหน่ายอย่างต่อเนื่อง


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

คำตอบ:


75

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

แน่นอนคุณสามารถระบุว่าจะใช้ที่เก็บสำรองอื่นได้หากต้องการ ดังนั้นหากคุณมีสแต็กที่คุณรู้ว่าจะไม่เติบโตมากนักให้บอกให้ใช้เวกเตอร์แทน deque หากนั่นเป็นสิ่งที่คุณต้องการ


1
แต่เมื่อรายการพอยน์เตอร์ไปยังบล็อกเพิ่มขึ้นรายการนี้จะต้องถูกจัดสรรใหม่เป็นครั้งคราวเช่นเดียวกับเวกเตอร์ โดยไม่มีอาการการเพิ่มประสิทธิภาพใด ๆ จะเกิดจากปัจจัยคงที่ที่ดีที่สุด และการจัดการตัววนซ้ำที่จำเป็นเพื่อทำการพุชและป๊อปอย่างถูกต้องนั้นซับซ้อนstd::dequeกว่าที่เป็นอยู่std::vectorมากและการดำเนินการเหล่านี้มีแนวโน้มที่จะใช้บ่อยกว่าการจัดสรรซ้ำ ฉันมีช่วงเวลาที่ยากลำบากที่เชื่อว่าstd::dequeจะเอาชนะได้std::vectorในทางปฏิบัติ
Marc van Leeuwen

@ Michael Burr: แล้วทำไมไม่ใช้listทำไมdeque?
bappak

@MarcvanLeeuwen เกี่ยวกับคุณบอกว่าคุณมีช่วงเวลาที่ยากลำบากในการเชื่อ ... คุณช่วยแสดงจุดยืนที่ชัดเจนได้ไหม คุณหมายความว่าตอนนี้คุณเชื่อว่าstd::dequeมีโอกาสเอาชนะstd::vectorในทางปฏิบัติหรือไม่หรือคุณหมายความว่าคุณยังสงสัยอยู่? ขอบคุณ.
aafulei

@fleix ฉันไม่เห็นว่าทำไมมันถึงสำคัญขนาดนั้นไม่ว่าฉันจะมีเวลาที่ง่ายกว่าโดยเชื่อว่ามันstd::dequeจะทำได้ดีพอ ๆ กับการstd::vectorใช้งานจริงหรือไม่ แต่สำหรับสิ่งที่คุ้มค่าประสบการณ์ส่วนตัวของฉันคือฉันต้องการโครงสร้างข้อมูลสแต็กและคิวไม่ใช่สำหรับงานที่มีขนาดใหญ่และมีความสำคัญเพียงงานเดียว แต่สำหรับงานเล็ก ๆ น้อย ๆ หลายครั้งที่โรยผ่านโค้ดของฉัน ด้วยเหตุนี้ฉันจึงสนใจพฤติกรรมของคนตัวเล็กมากกว่าคนกลุ่มใหญ่ และ deque ส่องแสงที่นั่นเป็นพิเศษ การตั้งค่าของฉันคือการไม่ใช้รายการที่เชื่อมโยงแบบเดี่ยว แต่ (ดำเนินการด้วยตนเอง) แทน แต่ระยะทางของคุณอาจแตกต่างกันไป
Marc van Leeuwen

12

ดูGuru ของ Herb Sutter ประจำสัปดาห์ที่ 54สำหรับข้อดีของเวกเตอร์และ deque ที่จะทำ

ฉันคิดว่าความไม่สอดคล้องกันระหว่าง priority_queue และคิวเป็นเพียงการที่คนต่างคนใช้มัน


2
priority_queue ไม่ได้ใช้ push / pop_front จริงและการอ้างอิงถึงองค์ประกอบที่นอกเหนือจากลำดับแรกจะไม่ถูกต้องโดยการดำเนินการฮีป ดังนั้นจะไม่มีประโยชน์ใด ๆ ของ deque ซึ่งแตกต่างจากกรณีของคิวปกติ
Potatoswatter

9
นอกจากนี้ยังpriority_queueต้องเรียงลำดับดังนั้นค่าใช้จ่ายในการเข้าถึงแบบสุ่มที่สูงขึ้นdeque::iteratorจึงเป็นปัญหามากขึ้น
Potatoswatter

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