Std क्यों है :: नक्शा लाल-काले पेड़ के रूप में लागू किया गया है?


194

लाल-काले पेड़ केstd::map रूप में क्यों लागू किया जाता है ?

वहाँ कई संतुलित बाइनरी सर्च ट्री (BST) हैं। लाल-काले पेड़ को चुनने में डिज़ाइन ट्रेड-ऑफ क्या थे?


26
हालाँकि मैंने देखा है कि सभी कार्यान्वयन एक आरबी-ट्री का उपयोग करते हैं, ध्यान दें कि यह अभी भी कार्यान्वयन-निर्भर है।
थॉमस

3
@Thomas। यह कार्यान्वयन-निर्भर है, इसलिए ऐसा क्यों है कि सभी कार्यान्वयन आरबी-पेड़ों का उपयोग करते हैं?
डेनिस गोरोडेटस्की

1
मैं वास्तव में यह जानना चाहूंगा कि क्या किसी एसटीएल कार्यान्वयनकर्ता ने एक स्किप सूची का उपयोग करने के बारे में सोचा है।
Matthieu M.

2
C ++ का मैप और सेट वास्तव में मैप और ऑर्डर किए गए सेट हैं। उन्हें हैश फ़ंक्शंस का उपयोग करके लागू नहीं किया गया है। हर प्रश्न लिया जाएगा O(logn)और नहीं O(1), लेकिन मूल्यों को हमेशा हल किया जाएगा। सी से शुरू ++ 11 (मुझे लगता है कि), देखते हैं unordered_mapऔर unordered_set, कि हैश फंक्शन का उपयोग करके लागू और जब वे पृथक नहीं किया जा, सबसे प्रश्नों और संचालन में संभव हो रहे हैं O(1)(औसतन)
SomethingSomething

@ थोमस जो सच है, लेकिन व्यवहार में उतना दिलचस्प नहीं है। मानक एक विशिष्ट एल्गोरिथ्म या मन में एल्गोरिदम के सेट के साथ जटिलता की गारंटी देता है।
जस्टिन मीनर्स

जवाबों:


126

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

जबकि दोनों एल्गोरिदम में इन्सर्ट / डिलीट ऑपरेशन्स O (लॉग एन) हैं, रेड-ब्लैक ट्री के मामले में री-बैलेंसिंग रोटेशन एक O (1) ऑपरेशन है, जबकि AVL के साथ यह O (लॉग एन) ऑपरेशन है, जिससे लॉग बनता है रेड-ब्लैक ट्री री-बैलेंसिंग स्टेज के इस पहलू में अधिक कुशल है और संभावित कारणों में से एक है कि इसका अधिक उपयोग किया जाता है।

लाल-काले पेड़ों का उपयोग अधिकांश संग्रह पुस्तकालयों में किया जाता है, जिसमें जावा और माइक्रोसॉफ्ट .NET फ्रेमवर्क से प्रसाद शामिल हैं।


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

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

6
RB ट्री "डिफ़ॉल्ट कार्यान्वयन" नहीं है। प्रत्येक कार्यान्वयनकर्ता एक कार्यान्वयन चुनता है। जहां तक ​​हम जानते हैं, उन्होंने सभी आरबी पेड़ों को चुना है, इसलिए संभवतः यह प्रदर्शन के लिए या कार्यान्वयन / रखरखाव में आसानी के लिए है। जैसा कि मैंने कहा, प्रदर्शन के लिए ब्रेकप्वाइंट का मतलब यह नहीं हो सकता है कि उन्हें लगता है कि लुकअप की तुलना में अधिक आवेषण / हटाए गए हैं, बस दोनों के बीच का अनुपात उस स्तर से ऊपर है जहां उन्हें लगता है कि आरबी शायद एवीएल को हरा देता है।
स्टीव जेसोप

9
@डेनिस: दुर्भाग्य से संख्या प्राप्त करने का एकमात्र तरीका std::mapकार्यान्वयन की एक सूची बनाना है , डेवलपर्स को ट्रैक करना है, और उनसे पूछना है कि उन्होंने निर्णय लेने के लिए किन मानदंडों का उपयोग किया है, इसलिए यह अटकलें बनी हुई हैं।
स्टीव जेसोप

4
संतुलन के निर्णय लेने के लिए आवश्यक सहायक सूचनाओं को संग्रहीत करने के लिए यह सब से छूट, प्रति-नोड है। लाल-काले पेड़ों को रंग का प्रतिनिधित्व करने के लिए 1-बिट की आवश्यकता होती है। एवीएल पेड़ों को कम से कम 2 बिट्स (-1, 0 या 1 का प्रतिनिधित्व करने के लिए) की आवश्यकता होती है।
SJHowe

47

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

std::map रेड-ब्लैक ट्री का उपयोग करता है क्योंकि यह नोड प्रविष्टि / विलोपन और खोज की गति के बीच एक उचित व्यापार बंद हो जाता है।


1
क्या अापको उस बारे में पूर्ण विशवास है??? मैं व्यक्तिगत रूप से सोचता हूं कि रेड-ब्लैक ट्री या तो अधिक जटिल है, कभी सरल नहीं। केवल एक चीज, आरडी-ब्लैक ट्री में है, एवीएल की तुलना में पुन: संतुलन कम होता है।
एरिक ओउलेट ने

1
@ सैद्धांतिक रूप से, सम्मिलन और विलोपन के लिए आर / बी पेड़ और एवीएल पेड़ दोनों में जटिलता ओ (लॉग एन) है। लेकिन ऑपरेशन की लागत का एक बड़ा हिस्सा रोटेशन है, जो इन दो पेड़ों के बीच अलग है। कृपया चर्चा करने के लिए देखें ।fogcreek.com/joelonsoftware/… उद्धरण: "एक AVL पेड़ को संतुलित करने के लिए O (लॉग एन) रोटेशन की आवश्यकता हो सकती है, जबकि एक लाल काले पेड़ को संतुलन में लाने के लिए अधिकांश दो घुमावों पर लगेगा (हालांकि यह हो सकता है) O (लॉग एन) नोड्स की जांच करने के लिए तय करें कि घुमाव कहां हैं)। " तदनुसार मेरी टिप्पणियों का संपादन किया।
webbertiger

27

एवीएल पेड़ों की अधिकतम ऊंचाई 1.44logn है, जबकि RB पेड़ों की अधिकतम 2logn है। एवीएल में एक तत्व डालने से पेड़ में एक बिंदु पर एक असंतुलन हो सकता है। पुनर्संतुलन सम्मिलन को पूरा करता है। एक नया पत्ता डालने के बाद, उस पत्ती के पूर्वजों को अद्यतन करने के लिए जड़ तक करना पड़ता है, या एक बिंदु तक होता है, जहां दो उपप्रकार समान गहराई के होते हैं। K nodes को अपडेट करने की संभावना 1/3 ^ k है। असंतुलन हे (1) है। किसी तत्व को हटाने से एक से अधिक असंतुलन (पेड़ की आधी गहराई तक) हो सकता है।

आरबी-पेड़ क्रम 4 के बी-पेड़ हैं जिन्हें बाइनरी सर्च ट्री के रूप में दर्शाया गया है। B-ट्री में 4-नोड दो स्तरों के बराबर BST में परिणाम करता है। सबसे खराब स्थिति में, पेड़ के सभी नोड्स 2-नोड्स होते हैं, जिसमें पत्ती के नीचे केवल 3-नोड्स की एक श्रृंखला होती है। वह पत्ती जड़ से 2logn की दूरी पर होगी।

जड़ से सम्मिलन बिंदु तक नीचे जाने पर, किसी को 4-नोड को 2-नोड में बदलना होगा, यह सुनिश्चित करने के लिए कि कोई भी प्रविष्टि एक पत्ती को संतृप्त नहीं करेगा। सम्मिलन से वापस आने पर, इन सभी नोड्स का विश्लेषण करना होगा ताकि यह सुनिश्चित हो सके कि वे 4-नोड्स का सही प्रतिनिधित्व करते हैं। यह भी पेड़ में नीचे जा रहा किया जा सकता है। वैश्विक लागत समान होगी। दुनिया में कोई भी चीज मुफ्त में नहीं मिलती! पेड़ से एक तत्व निकालना उसी क्रम का है।

इन सभी पेड़ों के लिए जरूरी है कि नोड्स ऊंचाई, वजन, रंग आदि के बारे में जानकारी लेते हैं। केवल सेप्ले के पेड़ ही ऐसी अतिरिक्त जानकारी से मुक्त होते हैं। लेकिन ज्यादातर लोग सेप्ले के पेड़ों से डरते हैं, क्योंकि उनकी संरचना की रामादेवी!

अंत में, पेड़ वजन घटाने की अनुमति देते हुए, नोड्स में वजन की जानकारी भी ले सकते हैं। विभिन्न योजनाएं लागू की जा सकती हैं। जब एक सबट्री में दूसरे सबट्री के तत्वों की संख्या से 3 गुना से अधिक हो तो उसे रीबैलेंस करना चाहिए। पुन: संतुलन फिर से या तो एक एकल या दोहरे रोटेशन किया जाता है। इसका मतलब सबसे खराब मामला 2.4logn का है। एक 3 के बजाय 2 बार के साथ दूर हो सकता है, बहुत बेहतर अनुपात, लेकिन इसका मतलब यह हो सकता है कि यहां और वहां असंतुलित होने वाले सबटाइटरों के 1% से थोड़ा कम थॉट्स छोड़ दें। मुश्किल!

किस प्रकार का पेड़ सबसे अच्छा है? सुनिश्चित करने के लिए ए.वी.एल. वे कोड के लिए सबसे सरल हैं, और लॉगन के पास उनकी सबसे खराब ऊंचाई है। 1000000 तत्वों के पेड़ के लिए, एक एवीएल अधिकतम ऊंचाई 29, एक आरबी 40, और वजन 36 या 50 के अनुपात के आधार पर संतुलित होगा।

बहुत सारे अन्य चर हैं: यादृच्छिकता, जोड़ का अनुपात, हटाता है, खोज आदि।


2
अच्छा उत्तर। लेकिन अगर AVL सबसे अच्छे हैं, तो मानक पुस्तकालय कार्यान्वयन std :: मैप आरबी के पेड़ के रूप में क्यों?
डेनिस गोरोडेट्स्की

14
मैं असहमत हूं कि एवीएल पेड़ निर्विवाद रूप से सर्वश्रेष्ठ हैं। हालाँकि, उनकी ऊँचाई कम है, उन्हें (कुल मिलाकर) लाल / काले पेड़ों (O (log n) रीबैलेंसिंग वर्क बनाम O (1) amortized rebalancing work) की तुलना में अधिक कार्य करने की आवश्यकता होती है)। सेप के पेड़ बहुत, बहुत बेहतर हो सकते हैं और आपके जोर से कि लोग उनसे डरते हैं निराधार हैं। वहाँ कोई सार्वभौमिक "सर्वश्रेष्ठ" वृक्ष संतुलन योजना नहीं है।
टेम्प्लेटेटीपीडिफ

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

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

25

पिछले उत्तर केवल पेड़ के विकल्प और लाल काले को संबोधित करते हैं जो शायद केवल ऐतिहासिक कारणों से बने हुए हैं।

हैश टेबल क्यों नहीं?

एक प्रकार के लिए केवल <ऑपरेटर (तुलना) की आवश्यकता होती है जिसका उपयोग एक पेड़ की कुंजी के रूप में किया जाता है। हालाँकि, हैश टेबल के लिए आवश्यक है कि प्रत्येक कुंजी प्रकार में एक hashफ़ंक्शन परिभाषित हो। सामान्य प्रोग्रामिंग के लिए एक न्यूनतम प्रकार की आवश्यकताओं को रखना बहुत महत्वपूर्ण है ताकि आप इसे विभिन्न प्रकार के प्रकार और एल्गोरिदम के साथ उपयोग कर सकें।

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

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

(C ++ 11 में हैश टेबल्स को नहीं जोड़ा गया था unordered_map। आप प्रलेखन से देख सकते हैं कि इसके लिए इनमें से कई विकल्पों को कॉन्फ़िगर करने के लिए नीतियां निर्धारित करने की आवश्यकता होती है।)

अन्य पेड़ों के बारे में क्या?

लाल काले पेड़ तेजी से देखने की पेशकश करते हैं और BSTs के विपरीत स्वयं संतुलन हैं। एक अन्य उपयोगकर्ता ने आत्म-संतुलन वाले एवीएल पेड़ पर इसके फायदे बताए।

अलेक्जेंडर स्टेपानोव (एसटीएल के निर्माता) ने कहा कि यदि वह std::mapफिर से लिखता है , तो वह लाल-काले पेड़ के बजाय बी * ट्री का उपयोग करेगा , क्योंकि यह आधुनिक मेमोरी कैश के लिए अधिक अनुकूल है।

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

क्या मानचित्रों को हमेशा पेड़ों का उपयोग करना चाहिए?

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

क्या मुझे मानचित्र का उपयोग करने की आवश्यकता है?

कैश के विचारों का अर्थ है कि यह शायद ही कभी उपयोग करने के लिए std::listया उन स्थितियों के लिए भी std::dequeअधिक समझ में आता है std:vectorजो हमें स्कूल में सिखाई गई थीं (जैसे सूची के बीच से एक तत्व को निकालना)। उसी तर्क को लागू करते हुए, लूप फॉर लीनियर खोज के लिए लूप का उपयोग करना अक्सर कुछ लुकअप के लिए मानचित्र बनाने की तुलना में अधिक कुशल और क्लीनर होता है।

बेशक पठनीय कंटेनर चुनना आमतौर पर प्रदर्शन से अधिक महत्वपूर्ण है।


3

2017-06-14 अपडेट करें: मैंने टिप्पणी करने के बाद webbertiger ने अपना उत्तर संपादित किया। मुझे यह बताना चाहिए कि इसका जवाब अब मेरी नज़र में बहुत बेहतर है। लेकिन मैंने अपना जवाब अतिरिक्त जानकारी के रूप में रखा ...

इस तथ्य के कारण कि मुझे लगता है कि पहला उत्तर गलत है (सुधार: दोनों नहीं) और तीसरे में गलत प्रतिज्ञान है। मुझे लगता है मुझे चीजों को स्पष्ट करना था ...

2 सबसे लोकप्रिय पेड़ एवीएल और रेड ब्लैक (आरबी) हैं। उपयोग में मुख्य अंतर है:

  • एवीएल: बेहतर अगर परामर्श का अनुपात (पढ़ें) हेरफेर (संशोधन) से बड़ा है। मेमोरी पैर प्रिंट आरबी से थोड़ा कम है (रंग के लिए आवश्यक बिट के कारण)।
  • आरबी: सामान्य मामलों में बेहतर है जहां परामर्श (पढ़ें) और हेरफेर (संशोधन) या परामर्श से अधिक संशोधन के बीच संतुलन है। लाल-काले झंडे के भंडारण के कारण थोड़ा बड़ा स्मृति पदचिह्न।

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

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


2

यह केवल आपके कार्यान्वयन का विकल्प है - उन्हें किसी भी संतुलित पेड़ के रूप में लागू किया जा सकता है। विभिन्न विकल्प मामूली अंतर के साथ सभी तुलनीय हैं। इसलिए कोई भी किसी भी रूप में अच्छा है।

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