2011-12-01 16 views
11

कुछ दिनों पहले this प्रश्न के परिणामस्वरूप कुछ ऐसी चीजें हैं जो std::deque::push_back/push_front के लिए जटिलता आवश्यकताओं के बारे में मुझे परेशान कर रही हैं, वास्तविक std::deque कार्यान्वयन में जंगली।std :: deque :: push_back/front

पिछले प्रश्न का उपरोक्त यह था कि इन परिचालनों में O(1) सबसे खराब केस जटिलता होना आवश्यक है। मैं सत्यापित कि यह वास्तव में c++11 में मामला था:

23.3.3.4 Deque संशोधक से

, सम्मिलित करने के लिए, धक्का/क़ायम करना सामने/वापस

जटिलता चर्चा करते हुए: जटिलता डाला तत्वों की संख्या में रेखीय है प्लस डेक की शुरुआत और अंत तक दूरी की कम दूरी। एक भी तत्व या तो शुरुआत है या एक Deque के अंत में सम्मिलित करना हमेशा स्थिर समय लगता है और , टी

यह अनुक्रमण के लिए O(1) जटिलता आवश्यकता के साथ संयुक्त है की एक निर्माता के लिए एक कॉल का कारण बनता है operator[] आदि के माध्यम से

मुद्दा यह है कि कार्यान्वयन इन आवश्यकताओं को सख्ती से पूरा नहीं करते हैं।

दोनों msvc और gccstd::deque कार्यान्वयन के संदर्भ में एक अवरुद्ध डेटा संरचना, (फिक्स्ड आकार) ब्लॉक, की ओर इशारा का एक गतिशील सरणी से मिलकर वह जगह है जहाँ प्रत्येक ब्लॉक भंडार डेटा तत्वों की एक संख्या।

सबसे खराब स्थिति में, push_back/front etc एक अतिरिक्त ब्लॉक आवंटित किया जाना आवश्यक बना सकते हैं (जो ठीक है - निर्धारित आकार आवंटन O(1) है), लेकिन यह भी आवश्यकता हो सकती है कि ब्लॉक संकेत के गतिशील सरणी आकार दिया जा - इस ठीक नहीं है, चूंकि यह O(m) है जहां m ब्लॉक की संख्या है, जो दिन के अंत में O(n) है।

स्पष्ट रूप से यह अभी भी O(1) जटिलता को बढ़ाया गया है और आम तौर पर m << n यह अभ्यास में बहुत तेज़ होने जा रहा है। लेकिन ऐसा लगता है कि अनुरूपता के साथ कोई मुद्दा है?

एक और बिंदु के रूप में, मुझे नहीं लगता कि आप एक डेटा संरचना कैसे डिजाइन कर सकते हैं जो और operator[] दोनों के लिए O(1) जटिलता दोनों को सख्ती से संतुष्ट करता है। आपके पास ब्लॉक पॉइंटर्स की एक लिंक-लिस्ट हो सकती है, लेकिन यह आपको वांछित operator[] व्यवहार नहीं देती है। क्या यह वास्तव में किया जा सकता है?

+0

संबंधित (लेकिन वास्तव में उत्तर दिया गया नहीं है): http://stackoverflow.com/questions/6292332/what-really-is-a-deque-in-stl –

+0

@NateKohl: हाँ बिल्कुल - और उस प्रश्न के उत्तर यह पुष्टि करने के लिए प्रतीत होता है कि आप सभी जटिलता आवश्यकताओं को सख्ती से संतुष्ट नहीं कर सकते हैं ... –

उत्तर

3

सी ++ 11 एफ डी आई में, हम पढ़ सकते हैं:

23.2.3 अनुक्रम कंटेनर [sequence.reqmts]

16/ टेबल 101 सूचियों संचालन के लिए प्रदान की जाती हैं कुछ प्रकार के अनुक्रम कंटेनर लेकिन दूसरों को नहीं।एक कार्यान्वयन इन कंटेनर को "कंटेनर" कॉलम में दिखाए गए सभी कंटेनर प्रकारों के लिए प्रदान करेगा, और उन्हें लागू करेगा ताकि निरंतर स्थिर समय लिया जा सके।

कहाँ टेबल 101वैकल्पिक अनुक्रम कंटेनर संचालन और सूचियों dequepush_back और push_front कार्यों के लिए नामित किया गया है।

इसलिए, यह आपके द्वारा उद्धृत अनुच्छेद में मामूली चूक की तरह लगता है। शायद एक दोष रिपोर्ट के लायक है?

ध्यान दें कि एकल अभी भी एक कन्स्ट्रक्टर को कॉल करता है।

+0

यह समस्या वास्तव में हाल ही में कुछ चर्चा पैदा कर रही है, उदाहरण के लिए देखें: http://stackoverflow.com/questions/8627373/what-data- संरचना-exactly-are-deques-in-c/8628035#8628035 और http://stackoverflow.com/questions/8631531/what-does-constant-complexity-really-mean-time-count-of-copies- –

+0

@DarrenEngwirda: पॉइंटर्स के लिए धन्यवाद :) मुझे लगता है कि असली मुद्दा यह है कि कोई भी नहीं जानता कि 'डेक' को कैसे कार्यान्वित किया जाए जो मानक आवश्यकताओं को पूरा करेगा, केवल अनुमान ... और मुझे या तो पता नहीं है। रैंडम एक्सेस/ओ (1) संदर्भ त्रयी का धक्का/संरक्षण जहां तक ​​मेरा संबंध है, यहां तक ​​कि अमूर्त ओ (1) पुश के साथ भी अप्रबंधनीय है। –

+0

इस उत्तर में मानक संदर्भ कुछ हद तक भ्रामक है, क्योंकि यह एकमात्र ऐसा स्थान नहीं है जहां जटिलता बाधित है। एक ही खंड से कोई पढ़ सकता है कि 'std :: vector' को अनुक्रमणित करना केवल ** अमूर्त ** निरंतर समय लेना आवश्यक है, लेकिन कहीं और यह स्पष्ट किया गया है कि इस मामले को वास्तव में किसी भी व्यक्तिगत उदाहरण के लिए निरंतर समय होना चाहिए। इसी प्रकार 'std :: deque :: push_front' विस्तृत प्रविष्टि (23.3.3.4:3 मेरी प्रतिलिपि में) कहता है ** ओपी में उद्धृत के रूप में ** हमेशा स्थिर समय ** लेता है, और यह स्पष्ट रूप से 23.2 में जो कहा गया है उसे ओवरराइड करना प्रतीत होता है .3: 16। –

0

मुझे संदेह है कि ब्लॉक पॉइंटर्स का पुनर्वितरण ज्यामितीय रूप से बढ़ते आकार के साथ किया जाता है - यह std :: vector के लिए एक आम चाल है। मुझे लगता है कि यह तकनीकी रूप से ओ (लॉग एम) है लेकिन जैसा कि आप एम < < एन इंगित करते हैं, इसलिए व्यावहारिक मामले के रूप में यह वास्तविक दुनिया के परिणामों को प्रभावित नहीं करता है।

+1

मुझे पता है कि आपका क्या मतलब है, लेकिन मानक वास्तव में अधिकतर कमरे को स्थानांतरित करने की अनुमति नहीं देता है, जिसके लिए निरंतर समय हमेशा * प्राप्त होता है। शायद मानक संशोधित किया जा सकता है? –

+2

दरअसल, ज्यामितीय विकास इसे * अमूर्त * ओ (1) ('वेक्टर' की तरह) बनाता है। –

संबंधित मुद्दे