2010-03-31 22 views
34

क्या कोई दो कार्यान्वयन (फायदे/नुकसान) के बीच मुख्य मतभेदों को समझा सकता है?चेनड हैश टेबल्स बनाम ओपन-एड्रेस किए गए हैश टेबल्स

लाइब्रेरी के लिए, किस कार्यान्वयन की अनुशंसा की जाती है?

उत्तर

46

Wikipedia's article on hash tables विभिन्न हैश टेबल योजनाओं का एक स्पष्ट रूप से बेहतर स्पष्टीकरण और अवलोकन देता है जो लोगों ने मेरे सिर के शीर्ष से बाहर निकलने में सक्षम है। असल में आप यहां सवाल पूछने से पहले उस लेख को पढ़ने से बेहतर हैं। :)

कहा ...

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

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

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

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

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

उपरोक्त सभी पर बहुत सारे बदलाव हैं। फिर, कृपया विकिपीडिया लेख देखें, यह वास्तव में काफी अच्छा है।

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

यदि आप जीटीके के साथ काम कर रहे हैं, उदाहरण के लिए, तो आप पाएंगे कि hash table in GLib अच्छा है।

+16

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

+3

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

+0

@AdrianMcCarthy - मैंने ध्यान नहीं दिया क्योंकि मैंने उस समय या तो इसके बारे में सोचा नहीं था।हैश टेबल हटाना के प्रदर्शन को ट्यून करना बहुत सूक्ष्म प्रतीत होता है, लेकिन बिल्कुल स्पष्ट नहीं है जब तक आप समस्या के बारे में सोचने से सावधानी बरतें! –

-1

यदि हैश तालिका में डाले गए आइटमों की संख्या तालिका के निर्माण के समय ज्ञात नहीं है, तो जंजीर हैश तालिका एड्रेसिंग खोलने के लिए बेहतर है।

भार कारक (वस्तुओं/तालिका आकार की संख्या) को बढ़ाने से खुली संबोधित हैश तालिकाओं में प्रमुख प्रदर्शन दंड का कारण बनता है, लेकिन प्रदर्शन केवल जंजीर हैश तालिकाओं में रैखिक रूप से घटता है।

यदि आप कम स्मृति से निपट रहे हैं और मेमोरी उपयोग को कम करना चाहते हैं, तो खुले पते के लिए जाएं। यदि आप स्मृति के बारे में चिंतित नहीं हैं और गति चाहते हैं, तो जंजीर हैश टेबल के लिए जाएं।

संदेह में, जंजीर हैश टेबल का उपयोग करें। अनुमानित से अधिक डेटा जोड़ना प्रदर्शन को क्रॉल में धीमा करने का कारण नहीं बनता है।

ओपन को संबोधित करते:

+0

ठीक है, अगर वस्तुओं की संख्या अग्रिम में ज्ञात नहीं है, तो मानक दृष्टिकोण केवल दो कारकों में तालिका को बढ़ाना होगा। यह खुली एड्रेसिंग या जंजीर हैश टेबल के साथ किया जा सकता है। एक जंजीर तालिका का उपयोग करने के लिए कोई आवश्यकता नहीं है, न ही इसे उस राज्य में चलाने के लिए जहां प्रदर्शन रैखिक हो जाता है। – cmaster

1

के बाद से उत्कृष्ट विवरण दिया जाता है, मैं तो बस आगे उदाहरण के लिए CLRS से लिया विज़ुअलाइज़ेशन शामिल था Open Addressing:

श्रृंखलन: Chaining:

+1

मेरा मानना ​​है कि आपके द्वारा लगाए गए पहले आंकड़े खुले पते के बजाय प्रत्यक्ष-संबोधन का चित्र है। –

1

मेरे समझ (सरल शब्दों में) यह है कि दोनों तरीकों में पेशेवर और विपक्ष हैं, हालांकि अधिकांश पुस्तकालय चेनिंग रणनीति का उपयोग करते हैं।

श्रृंखलन विधि:

यहाँ हैश तालिकाओं सरणी वस्तुओं का एक लिंक किए गए सूची में नक्शे। टक्कर की संख्या काफी छोटी है तो यह प्रभावी है। सबसे खराब स्थिति परिदृश्य O(n) है जहां एन तालिका में तत्वों की संख्या है।

ओपन रैखिक जांच के साथ संबोधित:

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

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

संबंधित मुद्दे