Computer >> कंप्यूटर >  >> प्रोग्रामिंग >> C++

बाइनरी ट्री के दो नोड्स के बीच की दूरी ज्ञात करने के लिए प्रश्न - C++ में O(logn) विधि

इस समस्या में, हमें एक बाइनरी ट्री दिया जाता है और हमें Q प्रश्न दिए जाते हैं। हमारा कार्य C++ में बाइनरी ट्री - O(logn) विधि के दोनोड्स के बीच की दूरी का पता लगाने के लिए क्वेरीज़ को हल करने के लिए एक प्रोग्राम बनाना है।

समस्या का विवरण

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

समस्या को समझने के लिए एक उदाहरण लेते हैं,

इनपुट :बाइनरी ट्री

बाइनरी ट्री के दो नोड्स के बीच की दूरी ज्ञात करने के लिए प्रश्न - C++ में O(logn) विधि

प्रश्न =3

Q1 -> [2, 6]

Q2 -> [4, 1]

Q3 -> [5, 3]

आउटपुट: 3, 2, 3

समाधान दृष्टिकोण

समस्या को हल करने के लिए, हम दूरी सूत्र का उपयोग करेंगे जो सबसे कम सामान्य पूर्वज (LCA) और उनकी दूरियों का उपयोग करता है।

दूरी (एन 1, एन 2) =दूरी (रूट, एन 1) + दूरी (रूट, एन 1) - 2 * दूरी (रूट, एलसीए)

समस्या को हल करने के लिए इन चरणों का पालन करेंगे,

  • प्रत्येक नोड अर्थात N1, N2, LCA के स्तरों का पता लगाएं।

  • फिर हम यूलर के टूरऑफ ट्री पर आधारित बाइनरी ट्री की सरणियाँ पाएंगे।

  • फिर हम LCA के लिए एक सेगमेंट ट्री बनाएंगे।

उदाहरण

#include <bits/stdc++.h>
#define MAX 1000
using namespace std;
int eulerArray[MAX];
int eIndex = 0;
int vis[MAX];
int L[MAX];
int H[MAX];
int level[MAX];
struct Node {
   int data;
   struct Node* left;
   struct Node* right;
};
struct Node* newNode(int data) {
   struct Node* temp = new struct Node;
   temp->data = data;
   temp->left = temp->right = NULL;
   return temp;
}
void FindNodeLevels(struct Node* root) {
   if (!root)
      return;
   queue<pair<struct Node*, int> > q;
   q.push({ root, 0 });
   pair<struct Node*, int> p;
   while (!q.empty()) {
      p = q.front();
      q.pop();
      level[p.first->data] = p.second;
      if (p.first->left)
         q.push({ p.first->left, p.second + 1 });
      if (p.first->right)
         q.push({ p.first->right, p.second + 1 });
   }
}
void createEulerTree(struct Node* root) {
   eulerArray[++eIndex] = root->data;
   if (root->left) {
      createEulerTree(root->left);
      eulerArray[++eIndex] = root->data;
   }
   if (root->right) {
      createEulerTree(root->right);
      eulerArray[++eIndex] = root->data;
   }
}
void creareEulerArray(int size) {
   for (int i = 1; i <= size; i++) {
      L[i] = level[eulerArray[i]];
      if (vis[eulerArray[i]] == 0) {
         H[eulerArray[i]] = i;
         vis[eulerArray[i]] = 1;
      }
   }
}
pair<int, int> seg[4 * MAX];
pair<int, int> min(pair<int, int> a, pair<int, int> b) {
   if (a.first <= b.first)
      return a;
   else
      return b;
}
pair<int, int> buildSegTree(int low, int high, int pos) {
   if (low == high) {
      seg[pos].first = L[low];
      seg[pos].second = low;
      return seg[pos];
   }
   int mid = low + (high - low) / 2;
   buildSegTree(low, mid, 2 * pos);
   buildSegTree(mid + 1, high, 2 * pos + 1);
   seg[pos] = min(seg[2 * pos], seg[2 * pos + 1]);
}
pair<int, int> LCA(int qlow, int qhigh, int low, int high, int pos) {
   if (qlow <= low && qhigh >= high)
      return seg[pos];
   if (qlow > high || qhigh < low)
      return { INT_MAX, 0 };
   int mid = low + (high - low) / 2;
   return min(LCA(qlow, qhigh, low, mid, 2 * pos), LCA(qlow, qhigh,mid + 1, high, 2 * pos +1));
}
int CalcNodeDistance(int node1, int node2, int size) {
   int prevn1 = node1, prevn2 = node2;
   node1 = H[node1];
   node2 = H[node2];
   if (node2 < node1)
      swap(node1, node2);
   int lca = LCA(node1, node2, 1, size, 1).second;
   lca = eulerArray[lca];
   return level[prevn1] + level[prevn2] - 2 * level[lca];
}
int main() {
   int N = 6;
   Node* root = newNode(1);
   root->left = newNode(2);
   root->right = newNode(3);
   root->left->left = newNode(4);
   root->left->right = newNode(5);
   root->right->left = newNode(6);
   FindNodeLevels(root);
   createEulerTree(root);
   creareEulerArray(2 * N - 1);
   buildSegTree(1, 2 * N - 1, 1);
   int Q = 4;
   int query[Q][2] = {{1, 5}, {4, 6}, {3, 4}, {2, 4} };
   for(int i = 0; i < Q; i++)
      cout<<"The distance between two nodes of binary tree is "<<CalcNodeDistance(query[i][0], query[i][1], 2 * N - 1)<<endl;
   return 0;
}

आउटपुट

The distance between two nodes of binary tree is 2
The distance between two nodes of binary tree is 4
The distance between two nodes of binary tree is 3
The distance between two nodes of binary tree is 1

  1. C++ में बाइनरी ट्री में अधिकतम लम्बवत योग ज्ञात कीजिए

    मान लीजिए कि हमारे पास एक बाइनरी ट्री है। कार्य ऊर्ध्वाधर क्रम ट्रैवर्सल में सभी नोड्स के अधिकतम योग को प्रिंट करना है। तो अगर पेड़ नीचे जैसा है - लंबवत क्रम ट्रैवर्सल इस प्रकार है - 4 2 1 + 5 + 6 = 12 3 + 8 = 11 7 9 यहां अधिकतम 12 है। दृष्टिकोण सरल है। हम वर्टिकल ऑर्डर ट्रैवर्सल करेंगे, फिर योग

  1. C++ प्रोग्रामिंग में बाइनरी ट्री में किन्हीं दो नोड्स के बीच प्रिंट पथ।

    हमें अलग-अलग नोड्स के एक बाइनरी ट्री और बाइनरी ट्री के दो नोड्स दिए गए हैं, जिसका बाइनरी ट्री में पथ हम प्रिंट करना चाहते हैं। उदाहरण के लिए - हम नोड 140 से 211 के बीच के पाथ को प्रिंट करना चाहते हैं, इसलिए इसका आउटपुट इस तरह होना चाहिए - Output: 140->3->10->211 विचार दो नोड्स के लिए रू

  1. पायथन में एक बाइनरी ट्री में दो नोड्स के बीच की दूरी का पता लगाने का कार्यक्रम

    मान लीजिए, हमें एक बाइनरी ट्री दिया जाता है और हमें बाइनरी ट्री में दो नोड्स के बीच की दूरी का पता लगाने के लिए कहा जाता है। हम दो नोड्स के बीच के किनारों को एक ग्राफ की तरह ढूंढते हैं और किनारों की संख्या या उनके बीच की दूरी को वापस कर देते हैं। पेड़ के नोड की संरचना नीचे दी गई है - data : <inte