हैश टेबल पर बाइनरी सर्च ट्री के क्या फायदे हैं?
हैश टेबल थीटा (1) समय में किसी भी तत्व को देख सकते हैं और एक तत्व को जोड़ना उतना ही आसान है .... लेकिन मुझे इस बात का पक्का यकीन नहीं है कि दूसरे तरीके से फायदे होंगे।
हैश टेबल पर बाइनरी सर्च ट्री के क्या फायदे हैं?
हैश टेबल थीटा (1) समय में किसी भी तत्व को देख सकते हैं और एक तत्व को जोड़ना उतना ही आसान है .... लेकिन मुझे इस बात का पक्का यकीन नहीं है कि दूसरे तरीके से फायदे होंगे।
जवाबों:
याद रखें कि बाइनरी सर्च ट्रीज़ (संदर्भ-आधारित) मेमोरी-कुशल हैं। वे आवश्यकता से अधिक मेमोरी आरक्षित नहीं करते हैं।
उदाहरण के लिए, यदि किसी हैश फ़ंक्शन में एक सीमा है R(h) = 0...100
, तो आपको 100 (पॉइंटर्स-इन) तत्वों की एक सरणी आवंटित करने की आवश्यकता है, भले ही आप सिर्फ 20 तत्व हैंशिंग हो। यदि आप एक ही जानकारी को संग्रहीत करने के लिए एक द्विआधारी खोज ट्री का उपयोग करते थे, तो आपको केवल उतना ही स्थान आवंटित करना होगा जितना कि आपको आवश्यक हो, साथ ही लिंक के बारे में कुछ मेटाडेटा भी।
एक फायदा जो किसी और ने नहीं बताया है वह यह है कि बाइनरी सर्च ट्री आपको श्रेणी खोजों को कुशलतापूर्वक करने की अनुमति देता है।
अपने विचार को स्पष्ट करने के लिए, मैं एक चरम मामला बनाना चाहता हूं। कहते हैं कि आप उन सभी तत्वों को प्राप्त करना चाहते हैं जिनकी कुंजी 0 से 5000 के बीच है। और वास्तव में केवल एक ऐसा तत्व है और 10000 अन्य तत्व हैं जिनकी कुंजी सीमा में नहीं है। BST खोज को काफी कुशलता से कर सकता है क्योंकि यह एक सबट्री नहीं खोजता है जिसका उत्तर देना असंभव है।
जबकि, आप हैश टेबल में श्रेणी खोज कैसे कर सकते हैं? आपको या तो हर बकेट स्पेस को इट्रेट करना होगा, जो O (n) है, या आपको यह देखना है कि 1,2,3,4 ... 5000 तक मौजूद है या नहीं। (0 और 5000 के बीच की कुंजियों के बारे में क्या एक अनंत सेट है? उदाहरण के लिए चाबियाँ दशमलव हो सकती हैं)
एक द्विआधारी वृक्ष का एक "फायदा" यह है कि सभी तत्वों को क्रम में सूचीबद्ध करने के लिए इसका पता लगाया जा सकता है। यह हश तालिका के साथ असंभव नहीं है, लेकिन हैशेड संरचना में एक सामान्य ऑपरेशन एक डिजाइन नहीं है।
अन्य सभी अच्छी टिप्पणियों के अलावा:
सामान्य रूप से हैश टेबल में बेहतर कैश व्यवहार होता है, जिसमें बाइनरी ट्री की तुलना में कम मेमोरी रीड की आवश्यकता होती है। एक हैश तालिका के लिए आप सामान्य रूप से केवल एक ही पढ़ते हैं, इससे पहले कि आप अपने डेटा को पकड़े हुए संदर्भ तक पहुंच सकें। बाइनरी ट्री, यदि यह एक संतुलित संस्करण है, तो k के क्रम में कुछ की आवश्यकता होती है * lg (n) मेमोरी कुछ निरंतर k के लिए पढ़ती है।
दूसरी ओर, यदि कोई दुश्मन आपके हैश-फंक्शन को जानता है, तो दुश्मन टकराव करने के लिए आपकी हैश टेबल को लागू कर सकता है, जिससे उसके प्रदर्शन में बाधा आ सकती है। वर्कअराउंड हैश-फ़ंक्शन को एक परिवार से यादृच्छिक रूप से चुनना है, लेकिन एक BST में यह नुकसान नहीं है। इसके अलावा, जब हैश टेबल का दबाव बहुत अधिक बढ़ जाता है, तो आप अक्सर हैश टेबल को बड़ा करने और उसे फिर से व्यवस्थित करते हैं, जो एक महंगा ऑपरेशन हो सकता है। BST का यहाँ सरल व्यवहार है और यह बहुत सारे डेटा को अचानक आवंटित करने और पुनः संचालन करने के लिए नहीं है।
पेड़ों में अंतिम औसत डेटा संरचना होती है। वे सूचियों के रूप में कार्य कर सकते हैं, आसानी से समानांतर ऑपरेशन के लिए विभाजित हो सकते हैं, ओ (lg n) के आदेश पर तेजी से हटाने, सम्मिलन और लुकअप कर सकते हैं । वे विशेष रूप से कुछ भी अच्छा नहीं करते हैं , लेकिन उनके पास कोई अत्यधिक बुरा व्यवहार नहीं है।
अंत में, BSTs हैश-तालिकाओं की तुलना में (शुद्ध) कार्यात्मक भाषाओं में लागू करने के लिए बहुत आसान हैं और उन्हें लागू होने के लिए विनाशकारी अपडेट की आवश्यकता नहीं है ( ऊपर पास्कल द्वारा दृढ़ता तर्क)।
BSTs are much easier to implement in (pure) functional languages compared to hash-tables
- वास्तव में? मैं अब एक कार्यात्मक भाषा सीखना चाहता हूं!
एक हैश टेबल पर एक बाइनरी ट्री का मुख्य लाभ यह है कि बाइनरी ट्री आपको दो अतिरिक्त ऑपरेशन देता है जो आप हैश टेबल के साथ (आसानी से, जल्दी से) नहीं कर सकते हैं
तत्व को निकटतम खोजें (आवश्यक नहीं के बराबर) कुछ मनमाना कुंजी मूल्य (या निकटतम ऊपर / नीचे)
क्रमबद्ध क्रम में पेड़ की सामग्री के माध्यम से पुनरावृति
दो जुड़े हुए हैं - बाइनरी ट्री अपनी सामग्री को क्रमबद्ध क्रम में रखता है, इसलिए जिन चीजों को क्रमबद्ध क्रम की आवश्यकता होती है, वे करना आसान होता है।
A (संतुलित) बाइनरी सर्च ट्री का यह भी फायदा है कि इसकी विषमता की जटिलता वास्तव में एक ऊपरी सीमा है, जबकि हैश टेबल के लिए "निरंतर" बार amortized बार होते हैं: यदि आपके पास अनुपयोगी हैश फ़ंक्शन है, तो आप रैखिक समय के लिए समाप्त हो सकते हैं निरंतर के बजाय।
पहली बार बनाए जाने पर एक हैशटेबल अधिक स्थान लेगा - इसमें उन तत्वों के लिए उपलब्ध स्लॉट होंगे जिन्हें अभी डाला जाना है (चाहे वे कभी भी सम्मिलित किए गए हों), एक द्विआधारी खोज वृक्ष केवल उतना ही बड़ा होगा जितना इसे आवश्यक है हो। इसके अलावा, जब एक हैश तालिका अधिक कमरे की जरूरत है, एक और संरचना के विस्तार कर सकता है समय लेने वाली हो, लेकिन उस कार्यान्वयन पर निर्भर हो सकता है।
एक द्विआधारी खोज ट्री को एक सतत इंटरफ़ेस के साथ लागू किया जा सकता है, जहां एक नया पेड़ वापस आ जाता है लेकिन पुराने पेड़ का अस्तित्व बना रहता है। ध्यान से लागू किया गया, पुराने और नए पेड़ अपने अधिकांश नोड्स साझा करते हैं। आप मानक हैश तालिका के साथ ऐसा नहीं कर सकते।
एक बाइनरी ट्री को खोजने और डालने के लिए धीमा है, लेकिन इसमें इन्फिक्स ट्रैवर्सल की बहुत अच्छी विशेषता है, जिसका अनिवार्य रूप से मतलब है कि आप क्रमबद्ध क्रम में पेड़ के नोड्स के माध्यम से पुनरावृत्ति कर सकते हैं।
एक हैश टेबल की प्रविष्टियों के माध्यम से Iterating बस बहुत मायने नहीं रखता है क्योंकि वे सभी स्मृति में बिखरे हुए हैं।
से कोडिंग साक्षात्कार क्रैकिंग, 6 संस्करण
हम एक संतुलित बाइनरी सर्च ट्री (BST) के साथ हैश टेबल को लागू कर सकते हैं। यह हमें O (लॉग एन) लुकअप समय देता है। इसका लाभ संभवतः कम जगह का उपयोग होता है, क्योंकि अब हम एक बड़े सरणी को आवंटित नहीं करते हैं। हम क्रम में कुंजियों के माध्यम से पुनरावृति भी कर सकते हैं, जो कभी-कभी उपयोगी हो सकते हैं।
BST, O (logn) समय में "findPredwardor" और "findSuccessor" ऑपरेशंस (अगले सबसे छोटे और अगले सबसे बड़े तत्वों को खोजने के लिए) प्रदान करते हैं, जो बहुत ही आसान ऑपरेशन भी हो सकते हैं। हैश टेबल उस समय दक्षता में प्रदान नहीं कर सकता।
यदि आप डेटा को सॉर्ट तरीके से एक्सेस करना चाहते हैं, तो हैश तालिका के समानांतर एक सॉर्ट की गई सूची को बनाए रखना होगा। एक अच्छा उदाहरण है .net में Dictionary। (देखें http://msdn.microsoft.com/en-us/library/3fcwy8h6.aspx )।
यह न केवल आवेषण को धीमा करने का साइड-इफेक्ट है, बल्कि यह बी-ट्री की तुलना में बड़ी मात्रा में मेमोरी का उपभोग करता है।
इसके अलावा, चूंकि बी-ट्री को सॉर्ट किया जाता है, इसलिए परिणामों की सीमाएं खोजना, या यूनियनों या मर्जों को निष्पादित करना सरल है।
यह उपयोग पर भी निर्भर करता है, हैश सटीक मिलान का पता लगाने की अनुमति देता है। यदि आप किसी श्रेणी के लिए क्वेरी करना चाहते हैं तो BST विकल्प है। मान लीजिए कि आपके पास बहुत सारा डेटा e1, e2, e3 ..... en है।
हैश टेबल से आप निरंतर समय में किसी भी तत्व का पता लगा सकते हैं।
यदि आप श्रेणी मानों को e41 से अधिक और e8 से कम खोजना चाहते हैं, तो BST शीघ्रता से पा सकते हैं।
मुख्य बात यह है कि टक्कर से बचने के लिए उपयोग किया गया हैश फ़ंक्शन है। बेशक, हम पूरी तरह से टकराव से बच नहीं सकते हैं, जिस स्थिति में हम चेनिंग या अन्य तरीकों का सहारा लेते हैं। यह सबसे बुरे मामलों में पुनर्प्राप्ति को अब निरंतर समय नहीं देता है।
एक बार पूरी तरह से, हैश टेबल को अपने बाल्टी आकार को बढ़ाना होगा और सभी तत्वों को फिर से कॉपी करना होगा। यह BST पर मौजूद अतिरिक्त लागत नहीं है।
हैश टेबल्स अनुक्रमण के लिए अच्छे नहीं हैं। जब आप एक सीमा खोज रहे हैं, तो बीएसटी बेहतर हैं। यही कारण है कि अधिकांश डेटाबेस इंडेक्स हैश टेबल्स के बजाय B + पेड़ों का उपयोग करते हैं
द्विआधारी खोज पेड़ शब्दकोश को लागू करने के लिए अच्छा विकल्प हैं यदि कुंजियों में कुछ कुल आदेश (चाबियाँ तुलनीय हैं) उन पर परिभाषित हैं और आप आदेश की जानकारी को संरक्षित करना चाहते हैं।
जैसा कि BST आदेश की जानकारी को संरक्षित करता है, यह आपको चार अतिरिक्त गतिशील सेट संचालन प्रदान करता है जो हैश टेबल का उपयोग करके (कुशलतापूर्वक) नहीं किया जा सकता है। ये ऑपरेशन हैं:
हर BST ऑपरेशन की तरह इन सभी कार्यों में O (H) की समय जटिलता है। इसके अतिरिक्त सभी संग्रहित कुंजियाँ BST में क्रमबद्ध रहती हैं, इस प्रकार आप पेड़ को क्रम से ट्रेस करके कुंजियों के क्रमबद्ध अनुक्रम को प्राप्त कर सकते हैं।
सारांश में, यदि आप चाहते हैं कि ऑपरेशन सम्मिलित हों, हटाएं और हटाएं तो प्रदर्शन में हैश तालिका अपराजेय (अधिकांश समय) है। लेकिन अगर आप चाहते हैं कि आपके ऊपर सूचीबद्ध कोई भी या सभी ऑपरेशन BST का उपयोग करें, तो अधिमानतः एक आत्म-संतुलन BST।
हैश टेबल का मुख्य लाभ यह है कि यह लगभग सभी ऑप्स को ~ = O (1) में करता है। और इसे समझना और लागू करना बहुत आसान है। यह कई "साक्षात्कार समस्याओं" को कुशलतापूर्वक हल करता है। तो अगर आप एक कोडिंग साक्षात्कार को क्रैक करना चाहते हैं, तो हैश टेबल के साथ सबसे अच्छे दोस्त बनाएं ;-)
एक हैशमप एक सेट एसोसिएटिव ऐरे है। तो, आपके इनपुट मानों की सरणी बाल्टियों में जमा हो जाती है। एक ओपन एड्रेसिंग स्कीम में, आपके पास एक बाल्टी के लिए एक पॉइंटर होता है, और हर बार जब आप एक नई वैल्यू को एक बाल्टी में जोड़ते हैं, तो आपको पता चलता है कि बाल्टी में कहाँ खाली जगह हैं। ऐसा करने के कुछ तरीके हैं- आप बाल्टी की शुरुआत में शुरू करते हैं और हर बार पॉइंटर को बढ़ाते हैं और परीक्षण करते हैं कि आपका कब्जा है या नहीं। इसे रेखीय जांच कहते हैं। फिर, आप ऐड की तरह एक द्विआधारी खोज कर सकते हैं, जहां आप बाल्टी की शुरुआत के बीच का अंतर दोगुना करते हैं और जहां आप हर बार मुक्त स्थान की खोज कर रहे हैं, वहां डबल या बैक अप करते हैं। इसे द्विघात जांच कहते हैं। ठीक है। अब इन दोनों विधियों में समस्या यह है कि यदि बाल्टी अगले बाल्टियों के पते में ओवरफ्लो हो जाती है, तो आपको इसकी आवश्यकता है-
ठीक है। लेकिन अगर आप एक लिंकलिस्ट का उपयोग करते हैं तो ऐसी समस्या सही नहीं होनी चाहिए? हां, लिंक की गई सूचियों में आपको यह समस्या नहीं है। लिंक की गई सूची के साथ शुरू करने के लिए प्रत्येक बाल्टी को ध्यान में रखते हुए, और यदि आपके पास एक बाल्टी में 100 तत्व हैं, तो आपको लिंक लिस्ट के अंत तक पहुंचने के लिए उन 100 तत्वों को पार करना होगा, इसलिए List.add (तत्व E) में समय लगेगा-
लिंकलिस्ट कार्यान्वयन का लाभ यह है कि आपको मेमोरी आवंटन ऑपरेशन और ओ (एन) ट्रांसफर / कॉपी की जरूरत नहीं है जैसा कि ओपन एड्रेसिंग कार्यान्वयन के मामले में है।
तो, ओ (एन) ऑपरेशन को कम करने का तरीका एक द्विआधारी खोज ट्री के कार्यान्वयन को परिवर्तित करना है जहां पाते हैं कि संचालन ओ (लॉग (एन)) हैं और आप इसके मूल्य के आधार पर इसकी स्थिति में तत्व जोड़ते हैं। BST की अतिरिक्त विशेषता यह है कि यह क्रमबद्ध होता है!
स्ट्रिंग कुंजियों के साथ उपयोग किए जाने पर बाइनरी सर्च ट्री तेजी से हो सकते हैं। खासकर जब तार लंबे होते हैं।
कम / अधिक की तुलना में बाइनरी सर्च ट्री जो स्ट्रिंग्स (जब वे बराबर नहीं होते हैं) के लिए तेज़ होते हैं। तो एक BST जल्दी से जवाब दे सकता है जब एक स्ट्रिंग नहीं पाया जाता है। जब यह पाया जाता है तो इसे केवल एक पूर्ण तुलना करने की आवश्यकता होगी।
एक हैश तालिका में। आपको स्ट्रिंग के हैश की गणना करने की आवश्यकता है और इसका मतलब है कि आपको हैश की गणना करने के लिए कम से कम एक बार सभी बाइट्स से गुजरना होगा। फिर, जब एक मिलान प्रविष्टि मिलती है।