सी # बाइनरी पेड़ों और शब्दकोश

वोट
15

मैं जब द्विआधारी खोज के पेड़ और जब शब्दकोशों उपयोग करने के लिए उपयोग करने के लिए की अवधारणा के साथ संघर्ष कर रहा हूँ।

अपने आवेदन में मैं एक छोटे से प्रयोग जो सी 5 पुस्तकालय इस्तेमाल किया किया था TreeDictionary(जो मेरा मानना है कि एक लाल-काले द्विआधारी खोज वृक्ष है), और सी # शब्दकोश। शब्दकोश / जोड़ने में हमेशा तेज थी संचालन खोजने के लिए और भी हमेशा कम स्मृति अंतरिक्ष का इस्तेमाल किया। उदाहरण के लिए, 16,809 पर <int, float>प्रविष्टियों, शब्दकोश 342 किबा इस्तेमाल किया 723 किबा पेड़ जबकि इस्तेमाल किया।

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

इसके अलावा, एक पक्ष प्रश्न के रूप में, किसी को पता है अगर वहाँ एक तेजी से + अधिक स्मृति कुशल डेटा भंडारण के लिये संरचना है <int, float>उल्लेख किसी एक संरचना से शब्दकोश प्रकार पहुँच के लिए जोड़े?

28/01/2010 को 02:46
का स्रोत उपयोगकर्ता
अन्य भाषाओं में...                            


6 जवाब

वोट
1

यह मेरे लिए आप समय से पहले अनुकूलन कर रहे हैं लगता है।

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

स्मृति / प्रदर्शन एक मुद्दा (जो शायद 20k- संख्या के लिए नहीं होगा), तो आप अन्य इंटरफेस क्रियान्वयन कर सकें, और जाँच जो एक bests काम करता है हो जाता है। आप कोड (जो कार्यान्वयन को छोड़कर आप उपयोग कर रहे) के बाकी हिस्सों में लगभग कुछ भी बदलने की जरूरत नहीं होगी।

28/01/2010 को 03:26
का स्रोत उपयोगकर्ता

वोट
1

यह भावना है कि एक पेड़ नोड एक शब्दकोश प्रविष्टि से अधिक संग्रहण की आवश्यकता होगी पड़ता है। एक द्विआधारी पेड़ नोड मूल्य और दोनों बाएँ और दाएँ subtrees संग्रहीत करना होगा। सामान्य Dictionary<TKey, TValue>मैं यह सोचते हैं रहा हूँ - - या तो प्रत्येक बकेट (मूल्य के अलावा एक सूचक / संदर्भ) या remapping के कुछ प्रकार (बस मूल्य) के लिए एक लिंक्ड सूची का उपयोग करता है एक हैश तालिका जो के रूप में कार्यान्वित किया जाता है। मैं परावर्तक में झांकना सुनिश्चित हो करने के लिए होगा, लेकिन इस सवाल के प्रयोजन के लिए मैं यह महत्वपूर्ण है कि नहीं लगता।

sparser हैश तालिका, भंडारण / स्मृति के मामले में कम कुशल। आप एक हैश तालिका (शब्दकोश) बना सकते हैं और 1 लाख करने के लिए अपनी क्षमता को प्रारंभ, और केवल 10,000 तत्वों के साथ इसे भरने, तो मैं बहुत यकीन है कि यह 10,000 नोड्स के साथ एक BST तुलना में बहुत अधिक स्मृति खा जाएगा हूँ।

फिर भी, मैं इस बारे में कोई चिंता नहीं होता है, तो नोड्स / कुंजी की राशि केवल हजारों में है। यही कारण है कि भौतिक RAM की गीगाबाइट की तुलना में, किलोबाइट में मापा जा रहा है।


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

28/01/2010 को 03:39
का स्रोत उपयोगकर्ता

वोट
0

एक पेड़ और एक हैश तालिका के लिए इंटरफ़ेस बहुत समान होना चाहिए (जो मेरा अनुमान है कि क्या अपने शब्दकोश से एक आधारित है)। हमेशा के आसपास keyed लुकअप घूमते हैं।

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

(कार्यात्मक भाषाओं में अक्सर वे संग्रह आप कर सकते हैं पेड़ के सबसे का फिर से उपयोग के रूप में यदि आप इसे करने के लिए छोटे संशोधन करने के लिए आधार के रूप पेड़ का उपयोग करें)।

28/01/2010 को 03:40
का स्रोत उपयोगकर्ता

वोट
0

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

मैं 2 के बीच स्मृति पदचिह्न में ज्यादा आकार की उम्मीद नहीं है लेकिन शब्दकोश आप एक बहुत तेजी से देखने दे देंगे। एक BST में एक आइटम खोजने के लिए आप (संभावित) पूरे पेड़ को पार करने की जरूरत है। लेकिन एक dictnary देखने करने के लिए आप बस कुंजी के आधार पर देखने।

28/01/2010 को 04:05
का स्रोत उपयोगकर्ता

वोट
8

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

मैं व्यक्तिगत रूप से इस तरह के एक सिद्धांत कभी नहीं सुना है। अभी भी यहां तक ​​कि, इसकी केवल एक सामान्य सिद्धांत, नहीं एक स्पष्ट तथ्य यह है ब्रह्मांड के कपड़े में etched।

आम तौर पर, शब्दकोश जुड़ा हुआ सूचियों की एक सरणी के आसपास वास्तव में सिर्फ एक फैंसी आवरण है। आप की तरह शब्दकोश कुछ में दर्ज करें:

LinkedList<Tuple<TKey, TValue>> list =
    internalArray[internalArray % key.GetHashCode()];
if (list.Exists(x => x.Key == key))
    throw new Exception("Key already exists");
list.AddLast(Tuple.Create(key, value));

तो इसके लगभग हे (1) आपरेशन। शब्दकोश ओ (internalArray.Length + एन) स्मृति, जहां n संग्रह में आइटम्स की संख्या है उपयोग करता है।

सामान्य BSTs में के रूप में लागू किया जा सकता:

  • लिंक्ड सूची, जो का उपयोग हे (एन) अंतरिक्ष, जहां n संग्रह में नंबर आइटम है।
  • सरणियों , जो O उपयोग (2 एच - जहां ज पेड़ की ऊंचाई है और n संग्रह में आइटम्स की संख्या है n) अंतरिक्ष।
    • के बाद से लाल-काले पेड़ों ओ (1.44 * एन) के एक घिरे ऊंचाई है, एक सरणी कार्यान्वयन के बारे में हे की एक घिरे स्मृति उपयोग (2 होना चाहिए 1.44n - एन)

बाधाओं रहे हैं, सी 5 TreeDictionary सरणियों, जो शायद बर्बाद अंतरिक्ष के लिए जिम्मेदार है का उपयोग कर कार्यान्वित किया जाता है।

क्या देता है? वहाँ कम से जहां BST के शब्दकोशों की तुलना में बेहतर कर रहे हैं एक बिंदु है?

शब्दकोश कुछ अवांछनीय गुण होते हैं:

  • वहाँ स्मृति के लिए पर्याप्त continugous ब्लॉक अपने शब्दकोश धारण करने के लिए नहीं हो सकता है, भले ही इसकी मेमोरी जरूरतों कुल उपलब्ध रैम की तुलना में से बहुत कम है।

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

    • Int32 की GetHashCodeविधि सचमुच है return this, तो आप एक मामले को खोजने के लिए जहां पूर्णांक कुंजी के साथ एक hashtable एक पेड़ शब्दकोश की तुलना में धीमी hardpressed होगी।

आरबी पेड़ कुछ वांछनीय गुण होते हैं:

  • आप पा सकते हैं / ओ में न्यूनतम और अधिकतम तत्वों को दूर (लॉग एन) समय हे (एन) समय एक शब्दकोश का उपयोग कर की तुलना में।

  • एक पेड़ लिंक्ड सूची के बजाय एक सरणी के रूप में लागू किया जाता है, पेड़ है आम तौर पर और अधिक स्थान की एक शब्दकोश की तुलना में कुशल।

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

  • आप जबकि आप एक सरणी में एक हैश तालिका डंप और यह सॉर्ट ही प्रभाव प्राप्त करने के लिए करना होगा, निरंतर अंतरिक्ष और हे (एन) समय में क्रमबद्ध क्रम में एक पेड़ के सभी तत्वों पार कर सकते हैं।

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

28/01/2010 को 04:16
का स्रोत उपयोगकर्ता

वोट
0

यदि आप विलंबता कीलें और हैश टकराव हमलों से अपनी डेटा संरचना की रक्षा करने की जरूरत है एक संतुलित BST बेहतर है।

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

.NET में एक और समस्या LOH है कि वहाँ है, और एक पर्याप्त रूप से बड़े शब्दकोश के साथ आप एक LOH विखंडन में चलाने है। इस मामले में आप एक BST उपयोग कर सकते हैं, बड़ा एल्गोरिथम जटिलता वर्ग के एक मूल्य का भुगतान।

संक्षेप में, एक BST आवंटन ढेर द्वारा समर्थित के साथ सबसे ज्यादा मामले हे (लॉग (एन)) समय मिलता है, hashtable के साथ हे (एन) सबसे ज्यादा मामले समय मिलता है।

BST हे (लॉग (एन)) औसत समय, बदतर कैश इलाके और अधिक ढेर आवंटन की कीमत पर आता है, लेकिन यह विलंबता की गारंटी देता है है और शब्दकोश हमलों और स्मृति विखंडन से सुरक्षित है।

टिप्पण लायक है कि BST भी अन्य प्लेटफार्मों पर स्मृति विखंडन करने के लिए एक विषय है, एक संकुचित कचरा कलेक्टर का उपयोग नहीं।

स्मृति आकार का सवाल है, .नेट Dictionary`2 वर्ग है क्योंकि यह एक ऑफ ढेर लिंक्ड सूची के रूप में डेटा है, जो केवल भंडार मूल्य संग्रहीत करता है और ऑफसेट जानकारी, अधिक स्मृति कुशल है। BST वस्तु हैडर स्टोर करने के लिए (के रूप में प्रत्येक नोड के ढेर पर एक वर्ग के उदाहरण है), दो संकेत दिए गए, और संतुलित पेड़ों के लिए कुछ संवर्धित पेड़ डेटा है। उदाहरण के लिए, एक लाल-काले पेड़ एक बूलियन के रूप में रंग (लाल या काले) व्याख्या की आवश्यकता होगी। यह कम से कम 6 मशीन शब्द है, अगर मैं गलत नहीं हूँ। तो, 64-बिट सिस्टम पर एक लाल-काले पेड़ में प्रत्येक नोड की एक न्यूनतम है:

हैडर = 24 बाइट्स बच्चे संकेत के लिए 2 शब्द = 16 बाइट्स 1 रंग के लिए शब्द = मूल्य 8 बाइट्स = 24 + 16 + 8 + 8 = 56 बाइट्स के लिए 8 बाइट्स कम से कम 1 शब्द के लिए 3 शब्द (+8 बाइट्स पेड़ एक माता पिता के नोड सूचक का उपयोग करता है)।

इसी समय, शब्दकोश प्रविष्टि के न्यूनतम आकार सिर्फ 16 बाइट्स होगा।

10/12/2018 को 13:18
का स्रोत उपयोगकर्ता

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more