कई डेटा संरचनाओं में प्रविष्टि की तुलना में विलोपन को लागू करने के लिए आमतौर पर क्यों बहुत मुश्किल है?


33

क्या आप किसी विशिष्ट कारण के बारे में सोच सकते हैं कि विलोपन आमतौर पर कई (अधिकांश?) डेटा संरचनाओं के लिए सम्मिलन की तुलना में लागू करने के लिए काफी कठिन है?

त्वरित उदाहरण: लिंक की गई सूची। सम्मिलन तुच्छ है, लेकिन हटाने के कुछ विशेष मामले हैं जो इसे काफी कठिन बनाते हैं। एवीएल और रेड-ब्लैक जैसे सेल्फ-बैलेंसिंग बाइनरी सर्च ट्री दर्दनाक डिलीट इम्प्लीमेंटेशन के क्लासिक उदाहरण हैं।

मैं यह कहना चाहूंगा कि इसका उस तरह से करना है जैसा ज्यादातर लोग सोचते हैं: हमारे लिए चीजों को रचनात्मक रूप से परिभाषित करना आसान है, जो अच्छी तरह से आसान सम्मिलन की ओर जाता है।


4
किस बारे popमें extract-min?
coredump

5
प्रोग्रामिंग (डेटा संरचनाओं और एल्गोरिदम के गुण) की तुलना में "हार्डर लागू करने के लिए" मनोविज्ञान (अनुभूति और मानव मन की ताकत और कमजोरियों) का मामला है।
आउटसाइड

1
जैसा कि मुझे लगता है कि coredump को आबंटित किया गया है, स्टैक्स को जोड़ने के लिए कम से कम हटाना आसान होना चाहिए (एक सरणी-समर्थित स्टैक के लिए, पॉपिंग केवल एक पॉइंटर डिक्रीमेंट है [1] जबकि पुश करने पर पूरे सरणी कॉपी की आवश्यकता हो सकती है यदि आप अधिकतम हिट करते हैं। सरणी)। इसके अलावा कुछ उपयोग के मामले हैं जहां यह माना जाता है कि सम्मिलन लगातार होगा और विलोपन कम होगा, लेकिन यह एक बहुत ही जादुई डेटा संरचना होगी जहां विलोपन की संख्या सम्मिलन से अधिक है। [१] आपको संभवतः स्मृति के रिसाव से बचने के लिए पॉपप किए गए ऑब्जेक्ट के अब अदृश्य संदर्भ को भी बंद कर देना चाहिए, जो मुझे याद है क्योंकि Liskov की पाठ्यपुस्तक नहीं थी
Foon

43
"वेटर, क्या आप इस सैंडविच में अधिक मेयो जोड़ सकते हैं?" "ज़रूर, कोई बात नहीं, सर।" "क्या आप भी सरसों निकाल सकते हैं?" "उह ......"
कोबाल्टक

3
घटाव इसके अलावा अधिक जटिल क्यों है? विभाजन (या प्रधान कारक) गुणन की तुलना में अधिक जटिल है? घातांक की तुलना में जड़ें अधिक जटिल हैं?
म्यू बहुत छोटा है

जवाबों:


69

यह सिर्फ मन की अवस्था से अधिक है; भौतिक (यानी डिजिटल) कारण हैं कि क्यों हटाना कठिन है।

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

संक्षेप में, प्रविष्टि आसान है क्योंकि आपको यह चुनने के लिए मिलता है कि आप कहाँ सम्मिलित करने जा रहे हैं। विलोपन कठिन है क्योंकि आप पहले से अनुमान नहीं लगा सकते हैं कि कौन सा आइटम हटने जा रहा है।


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

12
मैं इस बात से असहमत हूं कि सम्मिलन और विलोपन पूर्वानुमानिता में भिन्न हैं। एक सूची नोड के चारों ओर "पैचिंग" ठीक उसी तरह होता है, यदि इसके बजाय एक ही नोड को डाला जाए। किसी भी बिंदु पर किसी भी दिशा में कोई अनिश्चितता नहीं है, और किसी भी कंटेनर में आंतरिक तत्वों के बिना इसके तत्वों (उदाहरण के लिए एक संतुलित बाइनरी ट्री, तत्व ऑफसेट के बीच एक सख्त संबंध के साथ एक सरणी) में कोई "छेद" नहीं है। इसलिए, मुझे डर है कि मैं नहीं जानता कि आप यहाँ क्या बात कर रहे हैं।
sqykly

2
बहुत दिलचस्प है, लेकिन मैं कहूंगा कि तर्क याद किए जाते हैं। आप बिना किसी समस्या के सरल / तेज़ विलोपन के आसपास डेटा संरचनाएं व्यवस्थित कर सकते हैं। यह सिर्फ कम आम है, सबसे कम उपयोगी भी है।
luk32

@sqykly मुझे लगता है कि सूची खराब विकल्प उदाहरण थी क्योंकि मध्य सम्मिलन और मध्य संबंध समान रूप से कठिन हैं। एक मामला स्मृति को आवंटित करता है जहां दूसरा पुनः प्राप्त होता है। एक छेद को खोलता है जहां दूसरा छेद करता है। इसलिए सभी मामले ऐड से अधिक जटिल नहीं होते हैं।
ydobonebi

36

डालने की तुलना में इसे हटाना कठिन क्यों होता है? डेटा संरचनाएं विलोपन की तुलना में सम्मिलन के साथ अधिक डिज़ाइन की गई हैं, और ठीक ही ऐसा है।

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

इसके अतिरिक्त, प्रत्येक तत्व को क्रमिक रूप से हटाने में क्या उपयोग है? बस कुछ फ़ंक्शन को क्यों नहीं कहते हैं जो एक बार में सभी को साफ कर देता है (संभवतः केवल एक नया बनाकर)? इसके अलावा, डेटा संरचनाएं सबसे उपयोगी होती हैं जब वे वास्तव में कुछ होते हैं। तो सम्मिलन के रूप में कई विलोपन होने का मामला, व्यवहार में है, बहुत आम नहीं है।

जब आप किसी चीज का अनुकूलन करते हैं, तो आप उन चीजों का अनुकूलन करना चाहते हैं जो यह सबसे अधिक करती हैं और जो सबसे अधिक समय लेती हैं। सामान्य उपयोग में, डेटा संरचना के तत्वों का विलोपन सम्मिलन की तुलना में कम बार होता है।


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

1
उम्म, मुझे लगता है कि एक उदाहरण एक रिवर्स ऑर्डर किया हुआ वेक्टर हो सकता है। आप kतत्वों के एक बैच को बहुत तेजी से जोड़ सकते हैं : रिवर्स सॉर्ट इनपुट और मौजूदा वेक्टर के साथ विलय - O(k log k + n)। फिर आपके पास काफी जटिल सम्मिलन के साथ एक संरचना है लेकिन शीर्ष uतत्वों का सेवन तुच्छ और तेज है। बस अंतिम uऔर वेक्टर के अंत को आगे बढ़ाएं। हालाँकि, अगर किसी को कभी भी ऐसी किसी चीज़ की ज़रूरत होती है, तो मैं शापित हो जाऊँगा। मुझे उम्मीद है कि यह कम से कम आपके तर्क को मजबूत करता है।
luk32

क्या आप जो सबसे अधिक करते हैं उसके बजाय औसत उपयोग पैटर्न के लिए अनुकूलन नहीं करना चाहिए?
शिव

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

6

यह कठिन नहीं है।

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

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

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

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


1
मुझे असहमत होना पड़ेगा। AVL विलोपन एल्गोरिथ्म प्रविष्टि की तुलना में अधिक जटिल है। कुछ नोड हटाने के लिए आपको पूरे पेड़ को फिर से असंतुलित करना पड़ सकता है, जो आमतौर पर पुनरावर्ती रूप से किया जाता है, लेकिन गैर-पुनरावर्ती भी किया जा सकता है। सम्मिलन के लिए आपको ऐसा करने की आवश्यकता नहीं है। मुझे एल्गोरिथ्म की प्रगति के बारे में पता नहीं है, जहां इस तरह के पूरे पेड़-असंतुलन को सभी मामलों में टाला जा सकता है।
डेनिस

@ डेनिस: यह हो सकता है कि एवीएल पेड़ नियम के बजाय अपवाद का पालन करें।
आउटसाइड

@ आईटिस आईआईआरसी, सभी संतुलित खोज पेड़ों में अधिक जटिल विलोपन दिनचर्या (प्रविष्टि की तुलना में) है।
राफेल

बंद हैशिंग हैश टेबल के बारे में क्या ? सम्मिलन (अपेक्षाकृत) सीधा है, विलोपन कम से कम अवधारणा के लिए कठिन है क्योंकि आपको सभी "उस चीज़ को ठीक करना है जो सूचकांक X पर होना चाहिए था वर्तमान में सूचकांक Y पर है और हमें इसे ढूंढना है और इसे वापस लाना है" मुद्दे।
केविन

3

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

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


2
"अधिकांश डेटा संरचनाओं को सम्मिलित करने के लिए खोज की आवश्यकता नहीं होती है।" -- जैसे कि? मैं वास्तव में विपरीत दावा करूंगा। (आप "सम्मिलन की स्थिति" पाते हैं, जो बाद में फिर से उसी तत्व को खोजने के रूप में महंगी है।)
राफेल

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

... टीज़ को पेड़ माना जा सकता है; हालाँकि, यदि उनकी अपनी संरचना के रूप में वर्गीकृत किया गया है, तो सम्मिलन के दौरान "खोज" है या नहीं, यह बहस का विषय है, इसलिए मैं इसमें शामिल नहीं हूं। ध्यान दें कि डेटा संरचना सूची इंटरफ़ेस बनाम कार्यान्वयन को ध्यान में नहीं रखती है। इसके अलावा, आप कैसे गिनती करते हैं यह काफी हद तक इस बात पर निर्भर करता है कि आप किस तरह से वर्गीकृत करते हैं। मैं देखूंगा कि क्या मैं अधिक वस्तुनिष्ठ वक्तव्य के बारे में सोच सकता हूं।
outis

मैं मानता हूँ कि मेरे मन में डिक्शनरी / सेट इंटरफ़ेस था (जैसा कि CS में आम है)। वैसे भी, वह तालिका भ्रामक है और (iirc) कई स्थानों पर गलत भी है - विकिपीडिया, CS गलत सूचना का गड्ढा। : /
राफेल

0

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


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