आरबी पेड़, बी-ट्री या एवीएल पेड़ कब चुनें?


88

एक प्रोग्रामर के रूप में मुझे आरबी पेड़, बी-ट्री या एवीएल पेड़ का उपयोग करने पर विचार करना चाहिए? पसंद पर निर्णय लेने से पहले किन महत्वपूर्ण बिंदुओं पर विचार करने की आवश्यकता है?

क्या कोई प्रत्येक पेड़ की संरचना के लिए एक परिदृश्य के साथ समझा सकता है कि इसे प्रमुख बिंदुओं के संदर्भ में दूसरों के साथ क्यों चुना गया है?


10
खैर, मैं इस प्रश्न की सराहना करता हूं - वर्तमान में फास्टटाइल इंट्रावेलट्रीसेट बनाम इंट्रिब्यूटसेट की पसंद के साथ प्रस्तुत किया गया है।
यांग

जवाबों:


113

इसे एक चुटकी नमक के साथ लें:

B- ट्री जब आप हजारों से अधिक आइटम प्रबंधित कर रहे हैं और आप उन्हें डिस्क या किसी धीमे स्टोरेज माध्यम से पृष्ठांकित कर रहे हैं।

आरबी पेड़ जब आप काफी लगातार आवेषण कर रहे हैं, पेड़ पर हटाते हैं और पुनर्प्राप्ति करते हैं।

AVL पेड़ जब आपके आवेषण और हटाए गए आपके पुनर्प्राप्ति के सापेक्ष निराला होते हैं।


34
बस कुछ और विवरण जोड़ने के लिए: बी-पेड़ों में बच्चों की चर संख्या हो सकती है जो इसे कई रिकॉर्ड रखने की अनुमति देते हैं लेकिन फिर भी कम ऊंचाई के पेड़ को बनाए रखते हैं। आरबी ट्री में रीबैलेंसिंग के आस-पास कम सख्त नियम होते हैं जो एवीएल ट्री की तुलना में सम्मिलन / विलोपन को तेज बनाते हैं। इसके विपरीत, AVL पेड़ अधिक सख्ती से संतुलित होते हैं, इसलिए RB पेड़ की तुलना में लुकअप तेजी से होते हैं।
Pschang

आरबी पेड़ों के रिबैलेंस पर बेहतर प्रदर्शन ओ (1) होता है जो उन्हें रोल-बैक और रोल-फॉरवर्ड के साथ लगातार डेटास्ट्रक्चर के लिए अधिक उपयुक्त बनाता है।

20

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

B + पेड़ों में समस्याएँ होती हैं, हालाँकि - जैसे कि जब आप सम्मिलित करते हैं / हटाते समय नोड्स के भीतर इधर-उधर जाने वाले आइटम, उन आइटम्स पर पॉइंटर्स को अमान्य करते हैं। मेरे पास एक कंटेनर पुस्तकालय है जो "कर्सर रखरखाव" करता है - कर्सर खुद को लीफ नोड से जोड़ते हैं जो वे वर्तमान में एक लिंक की गई सूची में संदर्भित करते हैं, इसलिए वे स्वचालित रूप से तय या अमान्य हो सकते हैं। चूंकि एक या दो शाप देने वाले शायद ही कभी अधिक होते हैं, यह अच्छी तरह से काम करता है - लेकिन यह एक ही काम का एक अतिरिक्त सा है।

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

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

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

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



0

डेटा संरचनाओं का चयन करते समय आप ऐसे कारकों का व्यापार कर रहे हैं जैसे

  • अद्यतन की पुनर्प्राप्ति की गति की गति
  • कितनी अच्छी तरह से संरचना सबसे खराब स्थिति के संचालन का सामना करती है, उदाहरण के लिए एक क्रम में आने वाले रिकॉर्ड का सम्मिलन
  • जगह बर्बाद

मैं रॉबर्ट हार्वे द्वारा संदर्भित विकिपीडिया लेखों को पढ़कर शुरू करूंगा।

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


1
निष्पक्ष होने के लिए, ओपी ने पूछा when should I consider using, नहीं when should I consider implementing। जबकि अंतिम पैराग्राफ सच है, यह इस प्रश्न के संदर्भ में बहुत अधिक मूल्य प्रदान नहीं करता है। पुस्तकालयों के साथ भी, आपको प्रभावी ढंग से चुनने के लिए एल्गोरिदम को समझने की आवश्यकता है कि कौन सी संरचना आपके व्यवसाय की जरूरतों के लिए सबसे उपयुक्त है।
डैन बेहार्ड
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.