तत्वों को एक क्रमबद्ध सरणी में जोड़ना


31

ऐसा करने का सबसे तेज़ तरीका क्या होगा (एक एल्गोरिथम दृष्टिकोण से, साथ ही साथ एक व्यावहारिक मामला)?

मैं निम्नलिखित पंक्तियों के साथ कुछ सोच रहा था।

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

दूसरी ओर, अगर मुझे पता है कि मैं एक क्रमबद्ध सरणी के साथ शुरू करता हूं, तो मैं किसी दिए गए तत्व के लिए सम्मिलन बिंदु का पता लगाने के लिए एक द्विआधारी खोज का उपयोग कर सकता हूं।

मेरा कूबड़ यह है कि दूसरा तरीका लगभग इष्टतम है, लेकिन यह देखने के लिए उत्सुक है कि वहां क्या है।

यह सबसे अच्छा कैसे किया जा सकता है?


1
सबसे तेज़ तरीका, यदि आपको अक्सर ऐसा करना पड़ता है, तो पहली जगह में एक सरणी का उपयोग नहीं करना है।
रीयरियरपोस्ट

सेल्फ बैलेंसिंग बाइनरी ट्री का मतलब है?
सूंड

हाँ, संभवतः; जवाब देखें ...
reinierpost

जवाबों:


25

हम सरणी तत्व की संख्या को पढ़ते और लिखते हैं। बबल सॉर्ट करने के लिए, आपको एक्सेस की आवश्यकता होती है (अंत तक प्रारंभिक लेखन, फिर, सबसे खराब स्थिति में, दो रीड और दो एन स्वैप करने के लिए लिखते हैं )। बाइनरी खोज करने के लिए, हमें 2 लॉग एन + 2 एन + 1 ( बाइनरी खोज के लिए 2 लॉग एन , फिर, सबसे खराब स्थिति में, सरणी तत्वों को दाईं ओर शिफ्ट करने के लिए 2 एन की जरूरत है, फिर सरणी तत्व लिखने के लिए 1 इसकी उचित स्थिति)।1+4nn2logn+2n+12logn2n

तो दोनों विधियों में सरणी कार्यान्वयन के लिए एक ही जटिलता है, लेकिन बाइनरी सर्च विधि को लंबे समय में कम सरणी एक्सेस की आवश्यकता होती है ... asymptotically, आधे के रूप में कई। स्वाभाविक रूप से खेल में अन्य कारक हैं।

वास्तव में, आप बेहतर कार्यान्वयन का उपयोग कर सकते हैं और केवल वास्तविक सरणी एक्सेस की गणना कर सकते हैं (सम्मिलित किए जाने वाले तत्व तक पहुंच नहीं)। आप बबल सॉर्ट के लिए कर सकते हैं , और द्विआधारी खोज के लिए एन + 2 एन + 1 लॉग इन करें ... इसलिए यदि रजिस्टर / कैश एक्सेस सस्ता है और सरणी का उपयोग महंगा है, तो अंत से खोज और रास्ते में शिफ्टिंग (होशियार) प्रविष्टि के लिए बुलबुला सॉर्ट) बेहतर हो सकता है, हालांकि एसिम्पोटिक रूप से ऐसा नहीं है।2n+1logn+2n+1

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

ध्यान दें कि यदि आप n तत्वों के क्रमबद्ध सरणी में तत्वों को जोड़ना चाहते हैं, तो एक अच्छा विचार हो सकता है कि आप m आइटम को कुशलता से सॉर्ट करें , फिर दो सरणियों को मर्ज करें; इसके अलावा, सॉर्ट किए गए सरणियों को उदाहरण के लिए ढेर (ढेर प्रकार) का उपयोग करके कुशलता से बनाया जा सकता है।mnm


1
"एक हैश तालिका में ओ (1) प्रविष्टि और विलोपन हो सकते हैं" - आमतौर पर परिशोधित।
राफेल

8
परिशोधित की उम्मीद
जेएफई

BST में खोज और डालने (विकिपीडिया) के लिए, तो क्यों यह शीर्ष यहां चुनाव की सिफारिश नहीं की है? खोज और सम्मिलित करने के लिए O ( 2 l o g n )O(log n)O(2 log n)
कश्यप

8

यदि आपके पास ढेर का उपयोग न करने का कोई कारण है, तो बबल सॉर्ट के बजाय सम्मिलन सॉर्ट का उपयोग करने पर विचार करें। जब आपके पास कुछ अनसाल्टेड तत्व हों तो बेहतर है।


8

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

आइटम का पता लगाने के लिए सबसे तेज़ तरीका है जैसा कि आपने उल्लेख किया है, एक द्विआधारी खोज, जो , इसलिए कुल जटिलता होने वाली हैO(lgn) , जो कि आदेश पर है( n )O(n+lgn)O(n)

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

वैसे भी, मुझे इस समस्या के लिए बबल सॉर्ट को खींचने का कोई कारण नहीं दिखता है।


2
एल्गोरिदम की तुलना करते समय वेवेल पर बने रहना बहुत उपयोगी नहीं है जो सभी रैखिक समय लेते हैं। O
राफेल

स्नार्की होने के लिए +1 .. :-)
कश्यप

4

पैट्रिक87 ने यह सब बहुत अच्छी तरह से समझाया। लेकिन एक अतिरिक्त अनुकूलन जो आप कर सकते हैं वह एक परिपत्र बफर की तरह कुछ का उपयोग करना होगा: आप सम्मिलित तत्व की स्थिति के दाईं ओर आइटम को हमेशा की तरह स्थानांतरित कर सकते हैं। लेकिन आप आइटम को बाईं ओर सही स्थिति के बाईं ओर भी ले जा सकते हैं। ऐसा करने के लिए, आपको सरणी को परिपत्र के रूप में मानने की आवश्यकता है, अर्थात अंतिम आइटम पहले वाले से ठीक पहले है और इसके लिए आपको सूचकांक को रखने की आवश्यकता है जहां आइटम वर्तमान में शुरू होते हैं।

यदि आप ऐसा करते हैं, तो इसका मतलब यह हो सकता है कि आप लगभग आधे ऐरे एक्सेस के रूप में बना सकते हैं (आपके द्वारा सम्मिलित किए गए अनुक्रमित का समान वितरण मानकर)। स्थिति खोजने के लिए द्विआधारी खोज करने के मामले में, यह चुनना सही है कि क्या बाईं ओर या दाईं ओर शिफ्ट करना है। बबल सॉर्ट के मामले में, आपको शुरू करने से पहले सही ढंग से "अनुमान" लगाने की आवश्यकता है। लेकिन ऐसा करना सरल है: सरणी के मध्यिका के साथ सम्मिलित आइटम की तुलना करें, जिसे एकल सरणी एक्सेस में किया जा सकता है।


4

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


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