2011-06-23 5 views
6

मुझे अक्सर पदानुक्रमित वस्तुओं के पेड़ों को पार करने और रास्ते में प्रत्येक आइटम पर संचालन करने की आवश्यकता होती है। क्या सूची समझ में स्थानीय स्तर पर इस प्रकार के ऑपरेशन के लिए आम तौर पर स्वीकार्य नाम है? मैं पूछता हूं क्योंकि मुझे पहले पाइथन के zip function के बारे में पहले सीखना याद है, इससे पहले कि यह नेट फ्रेमवर्क में बराबर था और सोच रहा था कि इसका असामान्य लेकिन उचित नाम था।क्या इस प्रकार के गणितीय ऑपरेशन के लिए एक स्वीकार्य नाम है?

यहां कुछ सामान्यीकृत विधियां हैं जो वृक्ष संरचनाओं को ऊपर और नीचे की मरम्मत करती हैं और प्रत्येक आइटम को उनके सामने आने वाली उपज देती हैं।

public static IEnumerable<T> Ancestors<T>(T source, Func<T, T> selector) 
{ 
    do 
    { 
     yield return source; 
     source = selector(source); 
    } while (!Equals(source, default(T))); 
} 

public static IEnumerable<T> Descendents<T>(T source, 
              Func<T, IEnumerable<T>> selector) 
{ 
    var stack = new Stack<T>(); 
    stack.Push(source); 
    while (stack.Count > 0) 
    { 
     source = stack.Pop(); 
     yield return source; 
     var items = selector(source); 
     if (items != null) 
     { 
      foreach (var item in items) 
      { 
       stack.Push(item); 
      } 
     } 
    } 
} 
+0

कुछ प्रकार के फ़िल्टर किए गए पेड़ ट्रैवर्सल? मुझे नहीं पता कि इसका कोई विशेष नाम है या नहीं। मुझे नहीं लगता कि यह है। –

+0

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

+0

@ जॉर्ज: बिल्कुल, 'पूर्वजों' का एक निश्चित प्रकार का पदानुक्रम संबंध है। हकीकत में यह किसी भी दिशा में एक दोगुनी लिंक्ड सूची को पार करने या किसी भी प्रकार के मनमानी निशान का पालन करने के लिए आसानी से उपयोग किया जा सकता है। –

उत्तर

1

ये Tree Traversal काम करता है, भी सामान्यतः "पेड़ चलने" के रूप में जाना मानक हैं। अपने उदाहरण मानकीकृत नाम देना मुश्किल है क्योंकि ठोस चलने की रणनीति ज्ञात नहीं है :)

7

यह मानते हुए कि चयनकर्ता बच्चे नोड्स देता है, आपकी दूसरी विधि "सही पहली गहराई पहले" ट्रैवर्सल है। यही कारण है, अगर आप

 A 
    /\ 
    B  C 
/\ /\ 
D E F G 

तो था आपको मिल ए, सी, जी, एफ, बी, ई, डी आप "बी" से पहले "क्योंकि गहराई पहले" के रूप में गहरी के रूप में यह कर सकते हैं चला जाता है मिलता है "जी" इससे पहले कि यह एक और शाखा की कोशिश करता है। आपके विशेष उदाहरण में आपको बी से पहले सी मिलेगा क्योंकि यह बाएं से दाएं प्राथमिकता देता है।

यदि आप इसे

foreach (var item in items.Reverse()) 

करने के लिए बदल तो आप एक बाएं पहले गहराई से पहले ट्रेवर्सल है, जो कैसे ज्यादातर लोगों गहराई पहले ट्रेवर्सल के बारे में सोच मिल चाहते हैं।

यदि आपने स्टैक को कतार में बदल दिया है तो यह "चौड़ाई पहले" ट्रैवर्सल बन जाएगा। ए, बी, सी, डी, ई, एफ, जी। आप एक समय में एक संपूर्ण "स्तर" करते हैं।

अन्य ट्रैवर्सल भी हैं। ध्यान दें कि गहराई-प्रथम और चौड़ाई-पहली खोज दोनों में संपत्ति है जो माता-पिता नोड्स बच्चे नोड्स के सामने आते हैं। आपके पास "पोस्ट-ऑर्डर" ट्रैवर्सल भी हो सकते हैं जिसमें प्रत्येक नोड अपने बच्चों के बाद आता है।

बाइनरी पेड़ों में "इनऑर्डर" ट्रैवर्सल भी है। इस पेड़ के अंदरूनी भागना डी, बी, ई, ए, एफ, सी, जी है। यही है, हर बायां बच्चा अपने सभी पूर्वजों के सामने आता है, और हर सही बच्चा अपने सभी पूर्वजों के बाद आता है। एक अभ्यास के रूप में, क्या आप बाइनरी पेड़ पर एक इन-ऑर्डर ट्रैवर्सल लिख सकते हैं?

+1

छद्म कोड व्यायाम प्रतिक्रिया: 'फंक्शन इनऑर्डर (वृक्ष) {अगर (वृक्ष == शून्य) {वापसी;} इनऑर्डर (वृक्ष। लिफ्ट); आउटपुट (Tree.Value); इनऑर्डर (वृक्ष। राइट);} ' – Brian

+0

@ ब्रायन: सुपर। क्या आप बिना रिकर्सन के कर सकते हैं? –

+0

@Eric, आपको नोड के सामान्य ढेर का उपयोग करके कॉल स्टैक का अनुकरण करने और स्टैक पर प्रत्येक नोड के लिए ध्वज का उपयोग करके वापसी पता करने की आवश्यकता है। जब आप ढेर को पॉप करते हैं, तो आप ध्वज की जांच करते हैं कि क्या 1. "रिकर्स" बाएं या 2. (उपज) वर्तमान नोड और "रिकर्स" दाएं को वापस कर दें। तीसरे राज्य की कोई आवश्यकता नहीं है, जो मूल रूप से एक पूंछ कॉल अनुकूलन है। – svick

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