संतुलन वास्तव में एक सूक्ष्म संपत्ति है; आपको लगता है कि आप जानते हैं कि यह क्या है, लेकिन यह गलत होना बहुत आसान है। विशेष रूप से, यहां तक कि एरिक लिपर्ट का (अच्छा) उत्तर बंद है। ऐसा इसलिए है क्योंकि ऊंचाई की धारणा पर्याप्त नहीं है। आपको एक पेड़ की न्यूनतम और अधिकतम ऊंचाइयों की अवधारणा की आवश्यकता है (जहां न्यूनतम ऊंचाई जड़ से एक पत्ते तक कम से कम संख्या है, और अधिकतम है ... ठीक है, आपको चित्र मिलता है)। यह देखते हुए, हम संतुलन को परिभाषित कर सकते हैं:
एक पेड़ जहां किसी भी शाखा की अधिकतम ऊंचाई से अधिक नहीं है एक किसी भी शाखा की न्यूनतम ऊंचाई से अधिक है।
(यह वास्तव में तात्पर्य है कि शाखाएँ स्वयं संतुलित हैं; आप अधिकतम और न्यूनतम दोनों के लिए एक ही शाखा चुन सकते हैं।)
इस संपत्ति को सत्यापित करने के लिए आपको बस इतना करना चाहिए कि वर्तमान गहराई पर नज़र रखने वाला एक साधारण पेड़ ट्रैवर्सल है। पहली बार जब आप पीछे हटते हैं, तो यह आपको आधारभूत गहराई देता है। हर बार जब आप पीछे हटते हैं, तो आप आधार रेखा के खिलाफ नई गहराई की तुलना करते हैं
- यदि यह आधार रेखा के बराबर है, तो आप बस जारी रखें
- यदि यह एक से अधिक भिन्न है, तो पेड़ संतुलित नहीं है
- यदि यह एक बंद है, तो आप अब संतुलन के लिए सीमा जानते हैं, और बाद की सभी गहराई (जब आप बैकट्रैक के बारे में हैं) पहले या दूसरे मूल्य के होने चाहिए।
कोड में:
class Tree {
Tree left, right;
static interface Observer {
public void before();
public void after();
public boolean end();
}
static boolean traverse(Tree t, Observer o) {
if (t == null) {
return o.end();
} else {
o.before();
try {
if (traverse(left, o))
return traverse(right, o);
return false;
} finally {
o.after();
}
}
}
boolean balanced() {
final Integer[] heights = new Integer[2];
return traverse(this, new Observer() {
int h;
public void before() { h++; }
public void after() { h--; }
public boolean end() {
if (heights[0] == null) {
heights[0] = h;
} else if (Math.abs(heights[0] - h) > 1) {
return false;
} else if (heights[0] != h) {
if (heights[1] == null) {
heights[1] = h;
} else if (heights[1] != h) {
return false;
}
}
return true;
}
});
}
}
मुझे लगता है कि आप ऑब्जर्वर पैटर्न का उपयोग किए बिना ऐसा कर सकते हैं, लेकिन मुझे इस तरह से तर्क करना आसान लगता है।
[संपादित करें]: आप प्रत्येक पक्ष की ऊंचाई क्यों नहीं ले सकते। इस पेड़ पर विचार करें:
/\
/ \
/ \
/ \_____
/\ / \_
/ \ / / \
/\ C /\ / \
/ \ / \ /\ /\
A B D E F G H J
ठीक है, थोड़ा गंदा है, लेकिन जड़ के प्रत्येक पक्ष संतुलित है: C
गहराई 2, है A
, B
, D
, E
गहराई 3, और कर रहे हैं F
, G
, H
, J
गहराई 4. बाईं शाखा की ऊंचाई रहे हैं 2 (ऊंचाई याद है कि आप के रूप में पार कम हो जाती है है शाखा), सही शाखा की ऊंचाई 3. है फिर भी कुल मिलाकर पेड़ है नहीं संतुलित रूप में वहाँ के बीच 2 की ऊंचाई में अंतर होता है C
और F
। आपको एक न्यूनतम विनिर्देश की आवश्यकता होती है (हालांकि वास्तविक एल्गोरिथ्म कम जटिल हो सकता है क्योंकि केवल दो अनुमत ऊँचाई होनी चाहिए)।