2015-08-31 5 views
5

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

लेकिन मूल्य a और b के बीच खोज कैसे करें? (एक < ख)

चलो कहते हैं कि मैं इस पेड़

│    ┌── 125 
│   ┌── 122 
│   │ └── 120 
│  ┌── 117 
│  │ │ ┌── 113 
│  │ └── 112 
│  │  └── 108 
│ ┌── 86 
│ │ │ ┌── 85 
│ │ └── 72 
└── 59 
    │   ┌── 56 
    │  ┌── 52 
    │ ┌── 47 
    │ │ │ ┌── 43 
    │ │ └── 39 
    │ │  │ ┌── 38 
    │ │  └── 36 
    └── 28 
     │  ┌── 18 
     │ ┌── 15 
     └── 2 
      └── 1 

मैं एक विधि range(a,b)a और b समावेशी के बीच मान देने के लिए बनाना चाहते हैं करते हैं। (नोट: a और b पेड़ में आवश्यक नहीं कर रहे हैं!)

उदाहरण के लिए: range(53,112) वापस आ जाएगी 56,59,72,85,86,108,112

यहाँ मेरी छद्म कोड

/* recursive method */ 
range(a,b) 
    range(a,b,root); 

/* helper method */ 
range(a,b,node) 
    if (a <= node.value <= b) 
     if (node.left != null) and (node.value != a) 
      range(a,b,node.left) 

     print node.value 

     if (node.right != null) and (node.value != b) 
      range(a,b,node.right) 

    else if node.value < a 
     if (node.right != null) 
      range(a,b,node.right) 

    else // node.value > b 
     if (node.left != null) 
      range(a,b,node.left) 

है लेकिन मुझे लगता है मेरी विधि धीमी है।

उदाहरण के लिए, एक क्रमबद्ध सरणी में, हमें a और b पर बाइनरी खोज करना होगा और उनका संबंधित अनुक्रमणिका प्राप्त करना होगा। इसके बाद, हम a की अनुक्रमणिका से b की अनुक्रमणिका में पुन: प्रयास करते हैं।

क्या यह सच है कि बीएसटी कई मूल्यों को खोजने पर धीमा प्रदर्शन करेगा? क्या मेरे एल्गोरिदम को एक क्रमबद्ध सरणी के रूप में तेज़ी से सुधारना संभव है?

उत्तर

0

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

यदि आप पेड़ पर चलते समय फ्लाई पर प्रक्रिया कर सकते हैं तो यह कोई मुद्दा नहीं है (जैसे आप print के साथ कर रहे हैं)।

मैं हमेशा googling से पहले जवाब लिखने लगते हैं। यह पता चला है कि trees to answer range queries are a thing। स्पष्ट रूप से यह आमतौर पर 2 डी या 3 डी श्रेणियों के लिए किया जाता है (जहां प्रत्येक बिंदु में एक्स और वाई निर्देशांक होते हैं, उदाहरण के लिए), जो आप सॉर्ट किए गए सरणी के साथ नहीं कर सकते हैं। मुझे लगता है कि ऐसा इसलिए है क्योंकि यह जितना संभव हो उतना कुशल है, यह एक सूचक + लंबाई खिड़की को एक क्रमबद्ध सरणी में वापस करने के रूप में उतना कुशल नहीं है!

मैं कॉपी/विकिपीडिया से पूरे एल्गोरिथ्म, बस चालाक विचार पेस्ट करने के लिए नहीं जा रहा हूँ:

अंक कि अंतराल [x1, x2] में झूठ रिपोर्ट करने के लिए, हम खोज करके प्रारंभ करें x1 और x2 के लिए। पेड़ में कुछ शीर्ष पर, खोज पथ x1 और x2 करने के लिए वितरित हो जाएगा

इस तरह आप कुशलतापूर्वक, पूरे subtrees कि आप जानते हैं कि आपके रेंज में हो जाएगा पता लगाने विकिपीडिया देख सकते हैं और/या गूगल "पेड़ है रेंज क्वेरी "बहुत सारे विवरण के लिए।


मेरा प्री-गुगलिंग अवलोकन यह था कि आप तुलना से बच सकते हैं और बस कुछ सबट्री चल सकते हैं। आपके उदाहरण में, 86 के बाएं उपट्री सभी की सीमा में रहने की गारंटी है, क्योंकि हम जानते हैं कि वे सभी हैं> 59 और < 86, जो [a..b] से अधिक कठिन है। मैंने इस विशेष मामले की तलाश करने का कोई तरीका नहीं सोचा था जो इसे सहेजने से अधिक ओवरहेड खर्च नहीं करेगा।

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