वेक्टर बनाम एसटीएल में सूची


238

मैंने देखा कि प्रभावी एसटीएल में

वेक्टर अनुक्रम का प्रकार है जिसे डिफ़ॉल्ट रूप से उपयोग किया जाना चाहिए।

इसका क्या मतलब है? ऐसा लगता है कि दक्षता की अनदेखी vectorकुछ भी कर सकती है।

क्या कोई मुझे एक परिदृश्य की पेशकश कर सकता है जहां vectorएक संभव विकल्प नहीं है, लेकिन listइसका उपयोग किया जाना चाहिए?


6
हालाँकि यह नहीं है कि आपने क्या पूछा, यह इंगित करने योग्य है कि वेक्टर के लिए डिफ़ॉल्ट रूप से भी इसका मतलब है कि आप आसानी से पुराने कोड, सी लाइब्रेरी या गैर-टेम्पलेट लाइब्रेरी के साथ बातचीत कर सकते हैं, क्योंकि वेक्टर एक पॉइंटर के "पारंपरिक" डायनामिक सरणी के चारों ओर एक पतली आवरण है। और आकार।

18
Bjarne Strostrup ने वास्तव में एक परीक्षण किया जहां उन्होंने यादृच्छिक संख्याएँ उत्पन्न कीं और फिर उन्हें क्रमशः एक सूची और एक वेक्टर में जोड़ा। सम्मिलन इसलिए किए गए थे ताकि हर समय सूची / वेक्टर का आदेश दिया जाए। भले ही यह आम तौर पर "सूची डोमेन" है वेक्टर एक लार्ज मार्जिन द्वारा सूची से बाहर निकल गया। कारण यह है कि मेमोरी एक्सीस धीमा है और कैशिंग अनुक्रमिक डेटा के लिए बेहतर काम करता है। यह "GoingNative 2012" से अपने मुख्य वक्ता के रूप में सभी उपलब्ध है
चोरी


1
यदि आप बेज़र्न स्ट्रॉस्ट्रुप द्वारा कीनोट को देखना चाहते हैं जो @evading ने उल्लेख किया है, तो मैंने इसे यहां पाया: youtu.be/OB-bdWKwXsU?t=2672
brain56

जवाबों:


98

ऐसी स्थितियाँ जहाँ आप बहुत सी वस्तुओं को कहीं भी सम्मिलित करना चाहते हैं लेकिन एक क्रम का अंत बार-बार।

प्रत्येक विभिन्न प्रकार के कंटेनर के लिए जटिलता की गारंटी देखें:

मानक कंटेनरों की जटिलता की गारंटी क्या है?


2
अंत में तत्वों को सम्मिलित करना भी मायने रखता है क्योंकि इससे मेमोरी एलोकेशन और एलिमेंट कॉपी करने की लागत बढ़ सकती है। और भी, एक वेक्टर की शुरुआत में एनेट्स डालना असंभव के बगल में है, listहैpush_front
Notinlist

9
नहीं, वेक्टर के अंत में तत्वों को सम्मिलित करना निरंतर समय को परिशोधन करता है। मेमोरी का आवंटन केवल कभी-कभी होता है, और आप इसे रोकने के लिए वेक्टर का प्रचार कर सकते हैं। बेशक, अगर आप जरूरी निरंतर समय सम्मिलन की गारंटी देते हैं, तो मुझे लगता है कि यह अभी भी एक मुद्दा है।
ब्रायन

16
@Notinlist - क्या आपके लिए निम्नलिखित "असंभव के बगल में" है? v.insert (v.begin (), i)
मैनुअल

5
@Notinlist - मैं आपसे सहमत हूं, यह सिर्फ इतना है कि मैं नहीं चाहता था कि ओपी यह सोचें कि इंटरफ़ेस वहां नहीं है जब कोई स्वयं (प्रदर्शन) पैर में गोली मारना चाहता है।
मैनुअल

16
Bjarne Strostrup ने वास्तव में एक परीक्षण किया जहां उन्होंने यादृच्छिक संख्याएँ उत्पन्न कीं और फिर उन्हें क्रमशः एक सूची और एक वेक्टर में जोड़ा। सम्मिलन इसलिए किए गए थे ताकि हर समय सूची / वेक्टर का आदेश दिया जाए। भले ही यह आम तौर पर "सूची डोमेन" है वेक्टर एक लार्ज मार्जिन द्वारा सूची से बाहर निकल गया। कारण यह है कि मेमोरी एक्सीस धीमा है और कैशिंग अनुक्रमिक डेटा के लिए बेहतर काम करता है। यह "GoingNative 2012" से अपने मुख्य वक्ता के रूप में सभी उपलब्ध है
चोरी

409

वेक्टर:

  • सम्यक स्मृति।
  • भविष्य के तत्वों के लिए स्थान पूर्व-आवंटित करता है, इसलिए अतिरिक्त तत्वों की आवश्यकता होती है जो स्वयं तत्वों के लिए आवश्यक है।
  • प्रत्येक तत्व को केवल तत्व प्रकार के लिए स्थान की आवश्यकता होती है (कोई अतिरिक्त संकेत नहीं)।
  • किसी भी तत्व को जोड़ने पर किसी भी समय पूरे वेक्टर के लिए मेमोरी को फिर से आवंटित कर सकते हैं।
  • अंत में सम्मिलन स्थिर, परिशोधित समय है, लेकिन कहीं और सम्मिलन एक महंगा ओ (एन) हैं।
  • वेक्टर के अंत में स्थितियां निरंतर समय हैं, लेकिन बाकी के लिए यह O (n) है।
  • आप इसके तत्वों को बेतरतीब ढंग से एक्सेस कर सकते हैं।
  • यदि आप तत्वों को वेक्टर से जोड़ते या हटाते हैं, तो Iterators अमान्य हैं।
  • आप आसानी से अंतर्निहित सरणी पर प्राप्त कर सकते हैं यदि आपको तत्वों की एक सरणी की आवश्यकता है।

सूची:

  • गैर-सन्निहित स्मृति।
  • कोई पूर्व-आवंटित मेमोरी नहीं। सूची के लिए मेमोरी ओवरहेड निरंतर है।
  • प्रत्येक तत्व को नोड के लिए अतिरिक्त स्थान की आवश्यकता होती है जो सूची में अगले और पिछले तत्वों को इंगित करने वाले तत्व को शामिल करता है।
  • कभी भी पूरी सूची के लिए मेमोरी को फिर से आवंटित करने की आवश्यकता नहीं है क्योंकि आप एक तत्व जोड़ते हैं।
  • प्रविष्टि और इरेज़र सस्ते होते हैं चाहे वे सूची में कहीं भी हों।
  • यह splicing के साथ सूचियों को संयोजित करने के लिए सस्ता है।
  • आप तत्वों को बेतरतीब ढंग से एक्सेस नहीं कर सकते हैं, इसलिए सूची में किसी विशेष तत्व को प्राप्त करना महंगा हो सकता है।
  • जब आप सूची से तत्वों को जोड़ते या हटाते हैं, तब भी Iterators मान्य रहता है।
  • यदि आपको तत्वों की एक सरणी की आवश्यकता है, तो आपको एक नया बनाना होगा और उन सभी को इसमें जोड़ना होगा, क्योंकि कोई अंतर्निहित सरणी नहीं है।

सामान्य तौर पर, वेक्टर का उपयोग करें जब आपको परवाह नहीं है कि आप किस प्रकार के अनुक्रमिक कंटेनर का उपयोग कर रहे हैं, लेकिन यदि आप अंत के अलावा कंटेनर में और कहीं से भी कई सम्मिलन या erasures कर रहे हैं, तो आप चाहते हैं सूची का उपयोग करने के लिए। या यदि आपको रैंडम एक्सेस की आवश्यकता है, तो आप वेक्टर नहीं, लिस्ट चाहते हैं। इसके अलावा, स्वाभाविक रूप से ऐसे उदाहरण हैं जहां आपको अपने आवेदन के आधार पर एक या दूसरे की आवश्यकता है, लेकिन सामान्य तौर पर, वे अच्छे दिशानिर्देश हैं।


2
इसके अलावा, मुफ्त स्टोर से आवंटित करना मुफ्त नहीं है। :) एक वेक्टर में नई वस्तुओं को जोड़ने से ओ (लॉग एन) फ्री स्टोर आवंटन होता है, लेकिन आप reserve()उस ओ (1) को कम करने के लिए कॉल कर सकते हैं । एक सूची में नई वस्तुओं को जोड़ना (अर्थात उन्हें splicing नहीं) O (n) मुक्त स्टोर आवंटन करता है।
bk1e

7
एक और विचार यह है कि listजब आप तत्वों को मिटाते हैं तो स्मृति मुक्त हो जाती है , लेकिन vectorनहीं। एक vectorजब आप इसका आकार कम, जब तक आप का उपयोग अपनी क्षमता को कम नहीं करता swap()चाल।
bk1e

@ bk1e: मैं वास्तव में रिजर्व में आपकी चाल जानना चाहता हूं () और स्वैप () :)
Dzung Nguyen

2
@nXqd: यदि आपको एन तत्वों को वेक्टर में जोड़ने की आवश्यकता है, तो v.reserve (v.size () + N) को कॉल करें ताकि यह केवल एक फ्री स्टोर एलोकेशन करे। स्वैप () ट्रिक यहाँ है: stackoverflow.com/questions/253157/how-to-downsize-stdvector
bk1e

1
@simplename No. यह जो कहता है वह सही है। वेक्टर वेक्टर में वर्तमान में तत्वों के लिए स्थान से परे अतिरिक्त स्थान आवंटित करता है; इसके बाद अतिरिक्त क्षमता का उपयोग वेक्टर को विकसित करने के लिए किया जाता है ताकि बढ़ते हुए इसे O (1) से परिशोधित किया जा सके।
जोनाथन एम डेविस

35

यदि आपको अक्सर तत्वों को सम्मिलित करने की आवश्यकता नहीं होती है, तो एक वेक्टर अधिक कुशल होगा। यह एक सूची की तुलना में बेहतर CPU कैश इलाके है। दूसरे शब्दों में, एक तत्व तक पहुंचने से यह बहुत संभावना है कि अगला तत्व कैश में मौजूद है और धीमी रैम को पढ़ने के बिना पुनर्प्राप्त किया जा सकता है।


32

यहां अधिकांश उत्तर एक महत्वपूर्ण विवरण याद करते हैं: किस लिए?

आप क्या करना चाहते हैं?

यदि यह s का एक संग्रह है int, तो std::listहर परिदृश्य में खो जाएगा, भले ही यदि आप पुनः लोड कर सकते हैं, तो आप केवल सामने से हटा दें, आदि सूचियां ट्रैवर्स के लिए धीमी हैं, हर प्रविष्टि आपको एलोकेटर के साथ बातचीत का खर्च देती है। एक उदाहरण तैयार करना बहुत मुश्किल होगा, जहां list<int>धड़कता है vector<int>। और फिर भी, deque<int>बेहतर या करीबी हो सकता है, न कि सूचियों के उपयोग को सही ठहराते हुए, जिसमें अधिक मेमोरी ओवरहेड होगा।

हालाँकि, यदि आप डेटा के बड़े, बदसूरत ब्लब के साथ काम कर रहे हैं - और उनमें से कुछ - जब आप सम्मिलित करना चाहते हैं तो समग्र रूप से नहीं करना चाहते हैं, और reallocation के कारण नकल करना एक आपदा होगी - तो आप, हो सकता है, बेहतर हो। list<UglyBlob>की तुलना में vector<UglyBlob>

फिर भी, यदि आप स्विच करते हैं vector<UglyBlob*>या यहाँ तक कि vector<shared_ptr<UglyBlob> >, फिर से - सूची पिछड़ जाएगी।

इसलिए, एक्सेस पैटर्न, टारगेट एलिमेंट काउंट आदि अभी भी तुलना को प्रभावित करते हैं, लेकिन मेरे विचार में - तत्वों का आकार - कॉपी करने की लागत आदि।


1
एक और प्रतिबिंब, जो मुझे मेयर्स द्वारा "प्रभावी एसटीएल" पढ़ने पर मिला था: एक अजीबोगरीब संपत्ति हे (1) में होने list<T>की संभावना है । यदि आपको लगातार समय-समय पर घूमने की जरूरत है, तो सूची भी पसंद की संरचना हो सकती है;)splice
टॉमस गैंडर

+1 - यहां तक ​​कि इसका होना भी जरूरी नहीं है UglyBlob- यहां तक ​​कि कुछ स्ट्रिंग सदस्यों के साथ एक ऑब्जेक्ट भी आसानी से कॉपी करने के लिए निषेधात्मक रूप से महंगा हो सकता है, इसलिए वास्तविक धन का खर्च होगा । इसके अलावा: अंतरिक्ष को उपेक्षित न करें vectorकुछ दर्जन बाइट्स की होल्डिंग वस्तुओं की घातीय वृद्धि आकार में हो सकती है (यदि आप reserveपहले से नहीं कर सकते हैं )।
मार्टिन बा

के रूप में vector<smart_ptr<Large>>बनाम list<Large>- मैं कहता हूँ हैं, तो आप तत्वों के लिए रैंडम एक्सेस की आवश्यकता है, vectorसमझ में आता है। यदि आपको यादृच्छिक पहुंच की आवश्यकता नहीं है, तो listसरल प्रतीत होता है और समान रूप से प्रदर्शन करना चाहिए।
मार्टिन बा

19

Std की एक विशेष क्षमता :: सूची splicing है (किसी सूची में किसी संपूर्ण सूची को जोड़ने या स्थानांतरित करने की)।

या शायद अगर आपकी सामग्री कॉपी करने के लिए बहुत महंगी है। ऐसे मामले में यह सस्ता हो सकता है, उदाहरण के लिए, सूची के साथ संग्रह को सॉर्ट करना।

यह भी ध्यान दें कि यदि संग्रह छोटा है (और सामग्री को कॉपी करने के लिए विशेष रूप से महंगा नहीं है), एक वेक्टर अभी भी एक सूची को बेहतर बना सकता है, भले ही आप कहीं भी सम्मिलित करें और मिटा दें। एक सूची प्रत्येक नोड को व्यक्तिगत रूप से आवंटित करती है, और जो कुछ सरल वस्तुओं को चारों ओर ले जाने की तुलना में बहुत अधिक महंगा हो सकता है।

मुझे नहीं लगता कि बहुत कठिन नियम हैं। यह इस बात पर निर्भर करता है कि आप ज्यादातर कंटेनर के साथ क्या करना चाहते हैं, साथ ही साथ आप कंटेनर के बड़े और निहित प्रकार की अपेक्षा करते हैं। एक वेक्टर आम तौर पर एक सूची को रौंदता है, क्योंकि यह अपनी सामग्री को एक एकल सन्निहित ब्लॉक के रूप में आवंटित करता है (यह मूल रूप से एक गतिशील रूप से आवंटित सरणी है, और ज्यादातर परिस्थितियों में एक सरणी चीजों का एक गुच्छा रखने का सबसे कुशल तरीका है)।


1
+1। बंटवारे की अनदेखी की जाती है, लेकिन दुर्भाग्य से वांछित के रूप में निरंतर समय नहीं है। : ((यह नहीं हो सकता है यदि सूची :: आकार निरंतर-समय है।)

मैं काफी निश्चित सूची हूँ :: आकार (इस होने की अनुमति है) इस बहुत कारण के लिए रैखिक है।
चाचा

1
@ रेंजर: list::sizeजरूरी नहीं कि निरंतर समय हो। देखें stackoverflow.com/questions/228908/is-listsize-really-on और gcc.gnu.org/ml/libstdc++/2005-11/msg00219.html
Potatoswatter

@Potatoswatter: यह मानक अस्पष्ट है और इसके परिणामस्वरूप आप "आज्ञाकारी" कार्यान्वयन पर भरोसा नहीं कर सकते हैं यह एक समस्या का और भी अधिक बनाता है। पोर्टेबल और भरोसेमंद गारंटी पाने के लिए आपको सचमुच stdlib से बचना होगा।

@ रेंजर: हाँ, दुर्भाग्य से। मेरी वर्तमान परियोजना दृढ़ता से बंटवारे के संचालन पर निर्भर करती है और यह संरचना लगभग सीधे सी है। और भी दुर्भाग्य से, spliceविभिन्न सूचियों के बीच N3000 अनुक्रम में रैखिक जटिलता के रूप में निर्दिष्ट किया गया है और sizeविशेष रूप से निरंतर है। इसलिए, नौसिखियों को समायोजित करने के लिए, जो sizeया जो कुछ भी, उस पर एल्गोरिदम का एक पूरा वर्ग STL, या किसी भी "आज्ञाकारी" कंटेनरों की अवधि के लिए पहुंच से बाहर है।
पोटाटोस्वाटर

13

वैसे मेरी कक्षा के छात्र मुझे यह समझाने में असमर्थ हैं कि वेक्टर्स का उपयोग करना अधिक प्रभावी है, लेकिन वे मुझे सूचियों का उपयोग करने की सलाह देते हुए काफी खुश दिखते हैं।

यह मैं इसे समझता हूं

सूचियाँ : प्रत्येक आइटम में अगले या पिछले तत्व का एक पता होता है, इसलिए इस सुविधा के साथ, आप आइटम को यादृच्छिक कर सकते हैं, भले ही वे क्रमबद्ध न हों, क्रम परिवर्तित नहीं होगा: यदि आप स्मृति खंडित है तो यह कुशल है। लेकिन इसका एक और बहुत बड़ा फायदा भी है: आप आसानी से आइटम सम्मिलित / हटा सकते हैं, क्योंकि केवल एक चीज जो आपको करने की आवश्यकता है वह है कुछ संकेत। खामी: एक यादृच्छिक एकल आइटम को पढ़ने के लिए, आपको सही पता मिलने तक एक आइटम से दूसरे आइटम पर कूदना होगा।

वैक्टर : वैक्टर का उपयोग करते समय, मेमोरी को नियमित सरणियों की तरह अधिक व्यवस्थित किया जाता है: प्रत्येक एन-वें आइटम को थ्रेड (n-1) वें आइटम के बाद और पहले (n + 1) वें आइटम में संग्रहीत किया जाता है। यह सूची से बेहतर क्यों है? क्योंकि यह तेज़ रैंडम एक्सेस की अनुमति देता है। यहां बताया गया है कि: यदि आप किसी वेक्टर में किसी आइटम का आकार जानते हैं, और यदि वे मेमोरी में सन्निहित हैं, तो आप आसानी से अनुमान लगा सकते हैं कि एन-वें आइटम कहां है; आप जिस सूची को चाहते हैं, उसे पढ़ने के लिए आपको किसी सूची के सभी आइटम को ब्राउज़ करने की आवश्यकता नहीं है, वेक्टर के साथ, आप सीधे इसे पढ़ सकते हैं, एक सूची जिसके साथ आप नहीं कर सकते। दूसरी ओर, वेक्टर सरणी को संशोधित करें या एक मान बदलें जो बहुत अधिक धीमा है।

उन वस्तुओं पर नज़र रखने के लिए सूचियाँ अधिक उपयुक्त हैं जिन्हें स्मृति में जोड़ा / हटाया जा सकता है। जब आप किसी एकल आइटम की एक बड़ी मात्रा से एक तत्व का उपयोग करना चाहते हैं तो वैक्टर अधिक उपयुक्त होते हैं।

मुझे नहीं पता है कि सूचियों को कैसे अनुकूलित किया जाता है, लेकिन आपको यह जानना होगा कि यदि आप फास्ट रीड एक्सेस चाहते हैं, तो आपको वैक्टर का उपयोग करना चाहिए, क्योंकि एसटीएल फास्टन की सूचियों को कितना अच्छा करता है, यह वेक्टर की तुलना में रीड-एक्सेस में उतना तेज़ नहीं होगा।


"सदिश सरणी को संशोधित करें या एक मान बदलें बहुत अधिक धीमा है" - जैसा कि पढ़ा गया है, यह आपको उनके निम्न-स्तर और सन्निहित प्रकृति के कारण अच्छे प्रदर्शन के लिए पहले से ही सदिश होने के बारे में कही गई बात के विपरीत लगता है। आप मतलब था कि पुनः दिएvector अपने बदलने के कारण आकार धीमी गति से हो सकता है? फिर सहमत हुए, लेकिन उन मामलों में जहां reserve()इस्तेमाल किया जा सकता है, उन समस्याओं से बचा जाता है।
अंडरस्कोर_ड

10

मूल रूप से एक वेक्टर स्वचालित स्मृति प्रबंधन के साथ एक सरणी है। डेटा स्मृति में सन्निहित है। बीच में डेटा डालने की कोशिश करना एक महंगा ऑपरेशन है।

एक सूची में डेटा असंबंधित मेमोरी स्थानों में संग्रहीत किया जाता है। बीच में सम्मिलित करने से नए के लिए जगह बनाने के लिए कुछ डेटा की प्रतिलिपि बनाना शामिल नहीं है।

विशेष रूप से आपके प्रश्न का उत्तर देने के लिए मैं इस पृष्ठ को उद्धृत करूँगा

वैक्टर आमतौर पर तत्वों तक पहुंचने और अनुक्रम के अंत से तत्वों को जोड़ने या हटाने के लिए सबसे अधिक कुशल होते हैं। उन ऑपरेशनों के लिए जिनमें अंत के अलावा अन्य पदों पर तत्व सम्मिलित करना या निकालना शामिल है, वे देवताओं और सूचियों से भी बदतर प्रदर्शन करते हैं, और सूचियों की तुलना में कम सुसंगत पुनरावृत्तियों और संदर्भ होते हैं।


9

किसी भी समय आप पुनरावृत्तियों को अमान्य नहीं कर सकते।


2
लेकिन है कि क्या लगातार पूछे बिना iterators के बारे में है कि इस निष्कर्ष पर कूद कभी नहीं संदर्भ एक में dequeपर्याप्त होगा।
पोटाटोसवेटर

8

जब आप अनुक्रम के बीच में बहुत प्रविष्टि या विलोपन करते हैं। एक मेमोरी मैनेजर की तरह।


इसलिए उनके बीच का अंतर सिर्फ दक्षता है, कार्यात्मक मुद्दे के बारे में नहीं।
17

वे दोनों निश्चित रूप से तत्वों के अनुक्रम का मॉडल बनाते हैं। उपयोग में एक छोटा सा अंतर है, जैसा कि @dirkgently द्वारा उल्लेख किया गया है लेकिन आपको अपने "अक्सर किए गए" कार्यों की जटिलता को देखना होगा ताकि यह तय किया जा सके कि किस क्रम (@ उत्तर) का चयन करना है।
आरा

@ एस्किडूर - कुछ कार्यात्मक अंतर हैं। उदाहरण के लिए, केवल वेक्टर यादृच्छिक-अभिगम का समर्थन करता है (यानी, अनुक्रमित किया जा सकता है)।
मैनुअल

2
@skydoor: कार्यक्षमता प्रदर्शन में अनुवाद करती है। खराब प्रदर्शन कार्यक्षमता को बर्बाद कर सकता है। प्रदर्शन C ++ का लाभ है, सब के बाद।
पोटाटोस्वाटर

4

पुनरावृत्तियों की वैधता को संरक्षित करना एक सूची का उपयोग करने का एक कारण है। एक और है जब आप वस्तुओं को धक्का देते समय वेक्टर को पुनः प्राप्त नहीं करना चाहते हैं। इसे रिजर्व के एक बुद्धिमान उपयोग द्वारा प्रबंधित किया जा सकता है (), लेकिन कुछ मामलों में यह सिर्फ एक सूची का उपयोग करने के लिए आसान या अधिक संभव हो सकता है।


4

जब आप कंटेनरों के बीच वस्तुओं को स्थानांतरित करना चाहते हैं, तो आप उपयोग कर सकते हैं list::splice

उदाहरण के लिए, एक ग्राफ विभाजन एल्गोरिथ्म में लगातार बढ़ रही वस्तुओं की एक निरंतर संख्या हो सकती है जो कंटेनर की बढ़ती संख्या के बीच विभाजित होती है। वस्तुओं को एक बार आरंभीकृत किया जाना चाहिए और हमेशा स्मृति में एक ही स्थान पर रहना चाहिए। यह बहुत तेजी से उन्हें पुनः व्यवस्थित करके पुनः व्यवस्थित करने से बहुत तेज है।

संपादित करें: जैसा कि पुस्तकालय सी ++ 0x को लागू करने के लिए तैयार करते हैं, एक सूची में बाद में स्प्लिसिंग का सामान्य मामला अनुक्रम की लंबाई के साथ रैखिक जटिलता बन रहा है। ऐसा इसलिए है क्योंकि इसमें spliceअब तत्वों की संख्या गिनने के लिए अनुक्रम पर पुनरावृति करने की आवश्यकता है। (क्योंकि सूची को अपने आकार को रिकॉर्ड करने की आवश्यकता है।) बस सूची को गिनना और फिर से जोड़ना किसी भी विकल्प की तुलना में अभी भी तेज है, और पूरी सूची या एकल तत्व को स्प्लिस करना निरंतर जटिलता के साथ विशेष मामले हैं। लेकिन, यदि आपके पास विभाजन करने के लिए लंबे अनुक्रम हैं, तो आपको बेहतर, पुराने जमाने के गैर-अनुपालन वाले कंटेनर के लिए चारों ओर खुदाई करनी पड़ सकती है।


2

एकमात्र कठोर नियम जहां listइसका उपयोग किया जाना चाहिए, जहां आपको कंटेनर के तत्वों को पॉइंटर्स वितरित करने की आवश्यकता होती है।

इसके विपरीत vector, आप जानते हैं कि तत्वों की स्मृति को फिर से विभाजित नहीं किया जाएगा। यदि यह हो सकता है तो आपके पास अप्रयुक्त मेमोरी के लिए संकेत हो सकते हैं, जो कि सबसे बड़ी संख्या में है और नहीं सबसे खराब है SEGFAULT

(तकनीकी रूप vectorसे *_ptrभी काम करेगा, लेकिन उस स्थिति में आप इसका अनुकरण कर रहे हैं, listइसलिए यह सिर्फ शब्दार्थ है।)

अन्य नरम नियमों को एक कंटेनर के बीच में तत्वों को सम्मिलित करने के संभावित प्रदर्शन के मुद्दों के साथ listकरना पड़ता है , जिसमें बेहतर होगा।


2

इसे सरल बनाएं-
दिन के अंत में जब आप सी ++ में कंटेनरों को चुनने में उलझन में हों तो इस फ्लो चार्ट इमेज का उपयोग करें (मुझे धन्यवाद कहें): - यहां इमेज विवरण दर्ज करें

वेक्टर-
1. वेक्टर संक्रामक स्मृति पर आधारित है
। वेक्टर छोटे डेटा-सेट के लिए जाने का तरीका है।
3. वेक्टर डेटा-सेट पर ट्रैवर्स करते समय सबसे तेज़ प्रदर्शन करता है
। वेक्टर प्रविष्टि विलोपन विशाल डेटा-सेट पर धीमी है लेकिन बहुत छोटे के लिए तेज़ है

सूची-
1. सूची ढेर स्मृति पर आधारित है
। सूची बहुत विशाल डेटा-सेट के लिए जाने का तरीका है
। सूची छोटे डेटा-सेट को पार करने पर तुलनात्मक रूप से धीमी है, लेकिन विशाल डेटा-सेट
पर तेज़ है। सूची प्रविष्टि विलोपन तेज़ है विशाल डेटा-सेट लेकिन छोटे लोगों पर धीमा


1

सूचियाँ केवल stl में एक डबल-लिंक्डलिस्ट के लिए एक आवरण है, इस प्रकार सुविधा की पेशकश आप डी-लिंकलिस्ट से ओ (1) प्रविष्टि और विलोपन की उम्मीद कर सकते हैं। जबकि वैक्टर संक्रामक डेटा अनुक्रम होते हैं जो गतिशील सरणी की तरह काम करता है।


0

एक वेक्टर और सूची के मामले में , मेरे लिए मुख्य अंतर जो निम्नलिखित हैं:

वेक्टर

  • एक वेक्टर सन्निहित स्मृति में अपने तत्वों को संग्रहीत करता है। इसलिए, एक वेक्टर के अंदर यादृच्छिक अभिगम संभव है जिसका अर्थ है कि एक वेक्टर के एक तत्व तक पहुंचना बहुत तेज है क्योंकि हम उस तत्व तक पहुंचने के लिए आइटम इंडेक्स के साथ बस आधार पते को गुणा कर सकते हैं। वास्तव में, इस उद्देश्य के लिए केवल O (1) या निरंतर समय लगता है।

  • चूंकि एक वेक्टर मूल रूप से एक सरणी लपेटता है, हर बार जब आप वेक्टर (डायनेमिक सरणी) में एक तत्व सम्मिलित करते हैं, तो उसे नए तत्वों को समायोजित करने के लिए स्मृति के एक नए सन्निहित ब्लॉक को खोजने के लिए खुद को आकार देना पड़ता है जो समय-महंगा है।

  • यह किसी भी संकेत को इसके भीतर अन्य तत्वों को संग्रहीत करने के लिए अतिरिक्त मेमोरी का उपभोग नहीं करता है।

सूची

  • एक सूची अपने तत्वों को गैर-सन्निहित स्मृति में संग्रहीत करती है। इसलिए, किसी सूची के अंदर रैंडम एक्सेस संभव नहीं है, जिसका अर्थ है कि इसके तत्वों तक पहुंचने के लिए हमें पॉइंटर्स का उपयोग करना होगा और उस सूची को ट्रैक करना होगा जो वेक्टर के सापेक्ष धीमी है। यह O (n) या रैखिक समय लेता है जो O (1) की तुलना में धीमा है।

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

  • यह किसी विशेष तत्व से पहले और बाद में तत्व को स्टोर करने के लिए अतिरिक्त मेमोरी का उपभोग करता है।

इसलिए, इन अंतरों को ध्यान में रखते हुए, हम आम तौर पर एक निश्चित परिदृश्य में वेक्टर बनाम सूची के विजेता का फैसला करने के लिए स्मृति , लगातार यादृच्छिक अभिगम और सम्मिलन पर विचार करते हैं।


0

सूची डबली लिंक्ड सूची है इसलिए किसी तत्व को सम्मिलित करना और हटाना आसान है। हमें बस कुछ बिंदुओं को बदलना होगा, जबकि वेक्टर में अगर हम बीच में एक तत्व डालना चाहते हैं तो प्रत्येक तत्व को एक इंडेक्स द्वारा शिफ्ट करना होगा। साथ ही अगर वेक्टर का आकार भरा हुआ है तो उसे पहले अपना आकार बढ़ाना होगा। तो यह एक महंगा ऑपरेशन है। इसलिए जहां कहीं भी सम्मिलन और विलोपन कार्यों को करने की आवश्यकता होती है, ऐसे मामले में सूची का उपयोग किया जाना चाहिए।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.