गतिशील सरणी

गणना विज्ञान (कंप्यूटर विज्ञान) में, एक गतिशील सरणी, बढ़ने योग्य सरणी, आकार बदलने योग्य सरणी, गतिशील तालिका, उत्परिवर्तनीय सरणी, या सरणी सूची एक यादृच्छिक अभिगम, चर-आकार आँकड़े (डेटा) संरचना की सूची है जो अवयव को जोड़ने या निकालने की अनुमति देती है। यह कई आधुनिक मुख्यधारा की प्रोग्रामिंग भाषाओं में मानक पुस्तकालयों के साथ आपूर्ति की जाती है। गतिविज्ञान सरणियाँ स्थैतिक सरणियों की एक सीमा को पार कर जाती हैं, जिनकी एक निश्चित क्षमता होती है जिसे आवंटन के समय निर्दिष्ट करने की आवश्यकता होती है।

एक गतिशील सरणी गतिशील रूप से आवंटित सरणी या चर-लंबाई सरणी के समान नहीं है, इनमें से कोई भी एक सरणी है जिसका आकार सरणी आवंटित होने पर तय किया गया है, हालांकि एक गतिशील सरणी बैकएंड के रूप में इस तरह के निश्चित आकार के सरणी का उपयोग कर सकती है। उदाहरण के लिए देखें, java.util.ArrayList का स्रोत कोड ओपनजेडीके 6 से क्लास। 

परिबद्ध-आकार गतिशील सरणियाँ और क्षमता
निश्चित आकार की एक सरणी आवंटित करके एक साधारण गतिशील सरणी का निर्माण किया जा सकता है, आमतौर पर तुरंत आवश्यक तत्वों की संख्या से बड़ा। गतिशील सरणी के तत्वों को अंतर्निहित सरणी की शुरुआत में लगातार संग्रहित किया जाता है, और अंतर्निहित सरणी के अंत की शेष स्थिति आरक्षित या अप्रयुक्त होती है। आरक्षित स्थान का उपयोग करके समय जटिलता # लगातार समय में एक गतिशील सरणी के अंत में तत्वों को जोड़ा जा सकता है, जब तक कि यह स्थान पूरी तरह से खपत न हो जाए। जब सभी स्थान का उपभोग किया जाता है, और एक अतिरिक्त तत्व जोड़ा जाना है, तो अंतर्निहित निश्चित आकार के सरणी को आकार में बढ़ाना होगा। आमतौर पर आकार बदलना महंगा होता है क्योंकि इसमें एक नई अंतर्निहित सरणी आवंटित करना और प्रत्येक तत्व को मूल सरणी से कॉपी करना शामिल होता है। तत्वों को निरंतर समय में एक गतिशील सरणी के अंत से हटाया जा सकता है, क्योंकि कोई आकार बदलने की आवश्यकता नहीं है। गतिशील सरणी सामग्री द्वारा उपयोग किए जाने वाले तत्वों की संख्या इसका तार्किक आकार या आकार है, जबकि अंतर्निहित सरणी के आकार को गतिशील सरणी की क्षमता या भौतिक आकार कहा जाता है, जो डेटा को स्थानांतरित किए बिना अधिकतम संभव आकार है।

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

एक निश्चित आकार की सरणी उन अनुप्रयोगों में पर्याप्त होगी जहां अधिकतम तार्किक आकार निश्चित है (उदाहरण के लिए विनिर्देश द्वारा), या सरणी आवंटित होने से पहले गणना की जा सकती है। एक गतिशील सरणी को प्राथमिकता दी जा सकती है यदि:
 * अधिकतम तार्किक आकार अज्ञात है, या सरणी आवंटित होने से पहले गणना करना मुश्किल है
 * यह माना जाता है कि विनिर्देश द्वारा दिए गए अधिकतम तार्किक आकार में परिवर्तन होने की संभावना है
 * एक गतिशील सरणी का आकार बदलने की परिशोधित लागत प्रदर्शन या अनुक्रियाशीलता को महत्वपूर्ण रूप से प्रभावित नहीं करती है

ज्यामितीय विस्तार और परिशोधित लागत
कई बार आकार बदलने की अधिव्यय से बचने के लिए, गतिशील सरणी को बड़ी मात्रा में आकार दिया जाता है, जैसे आकार में दोगुना, और भविष्य के विस्तार के लिए आरक्षित स्थान का उपयोग करें। किसी तत्व को अंत में जोड़ने का कार्य निम्नानुसार कार्य कर सकता है:

प्रकार्य सम्मिलित करें समाप्त करें (डायनेरे a, तत्व e)   अगर (a.size == a.capacity) // a को उसकी वर्तमान क्षमता से दोगुना आकार दें: a.क्षमता ← a.क्षमता * 2 // (विषयसूची को यहां नए मेमोरी       स्थान पर अनुकरण करें) a [a आकार] ← e   a.साइज़ ← a.साइज़ + 1 क्योंकि n तत्व डाले जाते हैं, क्षमता एक ज्यामितीय प्रगति बनाती है। किसी भी स्थिर अनुपात द्वारा सरणी का विस्तार करना सुनिश्चित करता है कि n तत्वों को सम्मिलित करने में समग्र रूप से O(n) समय लगता है, जिसका अर्थ है कि प्रत्येक सम्मिलन में परिशोधित निरंतर समय लगता है। यदि इसका आकार एक निश्चित सीमा से कम हो जाता है, जैसे क्षमता का 30%, तो कई गतिशील सरणियाँ कुछ अंतर्निहित संग्रहण को भी हटा देती हैं। हिस्टैरिसीस प्रदान करने के लिए (बार-बार बढ़ने और सिकुड़ने से बचने के लिए एक स्थिर बैंड प्रदान करें) और परिशोधित निरंतर लागत के साथ सम्मिलन और निष्कासन के मिश्रित अनुक्रमों का समर्थन करने के लिए यह सीमा 1/a से दृढता से छोटी होनी चाहिए।

परिशोधित विश्लेषण पढ़ाते समय गतिशील सरणियाँ एक सामान्य उदाहरण हैं।

विकास कारक
गतिशील सरणी के लिए विकास कारक अंतराल-समय उद्योग-बंद और मेमोरी संभाजक में इस्तेमाल होने वाले एल्गोरिदम सहित कई कारकों पर निर्भर करता है। वृद्धि कारक a के लिए, प्रति सम्मिलन संचालन का औसत समय लगभग. यदि मेमोरी आवंटनकर्ता प्रथम अनुरूप एल्गोरिदम का उपयोग करता है, तो वृद्धि कारक मान जैसे कि a = 2 गतिशील सरणी प्रसारण को मेमोरी से बाहर चलाने का कारण बन सकता है, भले ही मेमोरी की एक महत्वपूर्ण मात्रा अभी भी उपलब्ध हो। सुनहरा अनुपात के साथ-साथ मूल्य 1.5 के प्रस्तावों सहित आदर्श विकास कारक मूल्यों पर विभिन्न चर्चाएँ हुई हैं। यद्यपि, कई पाठ्य पुस्तकें सादापन और विश्लेषण उद्देश्यों के लिए a = 2 का उपयोग करती हैं।

नीचे कई प्रचलित कार्यान्वयनों द्वारा उपयोग किए जाने वाले विकास कारक हैं:

प्रदर्शन
तत्वों को जोड़ने और हटाने के लिए नए कार्यों को जोड़ने के साथ गतिशील सरणी में एक सरणी के समान प्रदर्शन होता है:


 * किसी विशेष अनुक्रमणिका (निरंतर समय) पर मूल्य प्राप्त करना या समुच्चयन करना
 * क्रम में तत्वों पर ध्यान देना (रैखिक समय, अच्छा कैश प्रदर्शन)
 * सरणी के बीच में एक तत्व सम्मिलित करना या हटाना (रैखिक समय)
 * सरणी के अंत में एक तत्व सम्मिलित करना या हटाना (निरंतर परिशोधन समय)

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

श्रृंखलित की गई सूचियों की तुलना में, गतिशील सरणियों में तेजी से अनुक्रमण (निरंतर समय बनाम रैखिक समय) होता है और संदर्भ के बेहतर स्थान के कारण सामान्यतया पर तेजी से पुनरावृत्ति होती है; हालाँकि, गतिशील सरणियों को अव्यवस्थिततः स्थान पर सम्मिलित करने या हटाने के लिए रैखिक समय की आवश्यकता होती है, क्योंकि निम्नलिखित सभी तत्वों को स्थानांतरित किया जाना चाहिए, जबकि श्रृंखलित सूचियाँ निरंतर समय में ऐसा कर सकती हैं। इस असुविधा को गैप बफर और स्तरीय सदिश विचरण द्वारा कम किया गया है, जिसकी चर्चा नीचे विचरण के तहत की गई है। इसके अलावा, एक अत्यधिक खंडित मेमोरी क्षेत्र में, एक बड़े गतिशील सरणी के लिए सन्निहित स्थान खोजना महंगा या असंभव हो सकता है, जबकि श्रृंखलित सूचियों को संपूर्ण डेटा संरचना को सन्निहित रूप से संग्रहीत करने की आवश्यकता नहीं होती है।

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

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

गुडरिक एक गतिशील सरणियों एल्गोरिथम ने प्रस्तुत किया जिसे स्तरित सदिश कहा जाता है जो सरणियों में कहीं से भी सम्मिलन और विलोपन के लिए O(n1/k) प्रदर्शन प्रदान करता है, और O(k) प्राप्त और उत्पन्न करता है, जहां k ≥ 2 एक स्थिर मापदण्ड है।

हैशेड सरणी वृक्ष (HAT) 1996 में सितारस्की द्वारा प्रकाशित एक गतिशील सरणियों एल्गोरिथम है। हैशेड सरणी ट्री स्टोरेज स्पेस की n1/2 मात्रा को बर्बाद करता है, जहाँ n सरणी में तत्वों की संख्या है। हैशेड सरणी ट्री के अंत में वस्तुओं की एक श्रृंखला को जोड़ते समय एल्गोरिथ्म में O(1) परिशोधित प्रदर्शन होता है।

1999 के एक पेपर में, ब्रोडनिक एट अल। एक स्तरीय गतिशील सरणी डेटा संरचना, जो समय पर किसी भी बिंदु पर n तत्वों के लिए केवल n1/2 स्थान बर्बाद करती है, और वे यह दिखाते हुए एक निचली सीमा साबित करते हैं कि किसी भी गतिशील सरणी को इतना स्थान बर्बाद करना होगा यदि संचालन निरंतर समय को परिशोधित करना है। इसके अतिरिक्त, वे एक संस्करण प्रस्तुत करते हैं जहां बफर के बढ़ने और सिकुड़ने से न केवल परिशोधन होता है, बल्कि सबसे खराब समय भी होता है।

बागवेल (2002) ने वी लिस्ट एल्गोरिथम प्रस्तुत किया, जिसे एक गतिशील सरणी को अनुबंध करने के लिए अनुकूलित किया जा सकता है।

नाओव आकार बदलने योग्य सरणी - जिसे आकार बदलने योग्य सरणी का सबसे खराब कार्यान्वयन भी कहा जाता है - सरणी के आवंटित आकार को इसमें सम्मिलित सभी डेटा के लिए पर्याप्त रूप से बड़ा रखें, संभवतः सरणी में जोड़े गए प्रत्येक विषय के लिए रीयलोक को कॉल करके। C में एक आकार बदलने योग्य सरणी को लागू करने का सबसे सरल तरीका अनुभवहीन आकार बदलने योग्य सरणी है।वे किसी भी मेमोरी   को बर्बाद नहीं करते हैं, लेकिन सरणी के अंत में सम्मिलित होने में हमेशा Θ(n) समय लगता है। रैखिक रूप से बढ़ने वाली सरणियाँ पूर्व-आवंटन (अपशिष्ट) Θ (1) स्थान हर बार जब वे सरणी को फिर से आकार देती हैं, तो उन्हें नैवे आकार देने योग्य सरणियों की तुलना में कई गुना तेज बना देती हैं - सरणी के अंत में संलग्न होने में अभी भी Θ (n) समय लगता है लेकिन बहुत छोटे स्थिरांक के साथ। सरल आकार बदलने योग्य सरणियाँ और रैखिक रूप से बढ़ने वाली सरणियाँ तब उपयोगी हो सकती हैं जब अंतरिक्ष-बाधित अनुप्रयोग को बहुत से सूक्ष्म आकार बदलने योग्य सरणियों की आवश्यकता होती है; वे सामान्यतया पर एक शैक्षिक उदाहरण के रूप में भी उपयोग किए जाते हैं जो तेजी से बढ़ते गतिशील सरणियों के लिए अग्रणी होते हैं।

भाषा समर्थन
सी ++  और रस्ट  (प्रोग्रामिंग भाषा)   गतिशील सरणियों के कार्यान्वयन हैं, जैसा कि हैं जावा (प्रोग्रामिंग भाषा) API और NET फ्रेमवर्क के साथ प्रदान की जाने वाली सारणी सूची कक्षाएं हैं।

NET फ्रेमवर्क के संस्करण 2.0 के साथ आपूर्ति की गई सामान्य सूची <> वर्ग को गतिशील सरणियों के साथ भी लागू किया गया है। स्मॉलटॉक का आदेशित संग्रह गतिशील आरम्भ और अंत-सूचकांक के साथ एक गतिशील सरणिया है, जिससे पहले घटक को भी O(1) हटा दिया जाता है।

पायथन सूची डेटा प्रकार कार्यान्वयन एक गतिशील सरणी है जिसका विकास स्वरूप :0, 4, 8, 16, 24, 32, 40, 52, 64, 76, ...है

डेल्फी (प्रोग्रामिंग भाषा) और डी (प्रोग्रामिंग भाषा) भाषा के मूल में गतिशील सरणियों को प्रवर्तित करते हैं।

एडा (प्रोग्रामिंग लैंग्वेज) सामान्य संवेष्टन किसी दिए गए उपप्रकार के लिए गतिशील सरणी कार्यान्वयन प्रदान करता है।

पर्ल और रूबी_(प्रोग्रामिंग_लैंग्वेज) जैसी कई स्क्रिप्टिंग भाषाएं में निर्मित आदिम डेटा प्रकार के रूप में गतिशील सरणियाँ प्रदान करती हैं।

कई क्रॉस-प्लेटफ़ॉर्म फ्रेमवर्क C (प्रोग्रामिंग भाषा) के लिए गतिशील सरणी कार्यान्वयन प्रदान करते हैं, जिनमें सम्मिलित हैं    तथा   बीजकोष  संस्थान में, और   तथा  ग्लिब.में।

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

बाहरी संबंध

 * NIST Dictionary of Algorithms and Data Structures: Dynamic array
 * VPOOL - C language implementation of dynamic array.
 * CollectionSpy &mdash; A Java profiler with explicit support for debugging ArrayList- and Vector-related issues.
 * Open Data Structures - Chapter 2 - Array-Based Lists, Pat Morin