कैसे यथा-स्थान द्विआधारी खोज वृक्ष, यानी किसी बाइनरी पेड़ कन्वर्ट करने के लिए, हम किसी भी अतिरिक्त स्थान का उपयोग नहीं कर सकते हैं।
कैसे द्विआधारी खोज के पेड़ से एक द्विआधारी पेड़ कन्वर्ट करने के लिए यथा-स्थान, यानी, हम किसी भी अतिरिक्त जगह उपयोग नहीं कर सकते
एक द्विआधारी पेड़ आमतौर पर है एक द्विआधारी खोज वृक्ष, जिस स्थिति में कोई रूपांतरण की आवश्यकता है।
शायद आप आप क्या से परिवर्तित कर रहे हैं की संरचना को स्पष्ट करने की जरूरत है। अपने स्रोत पेड़ असंतुलित है? यह कुंजी आप पर खोज करना चाहते द्वारा आदेश दिया नहीं है? कैसे आप स्रोत पेड़ पर आए?
ठीक है, अगर यह एक साक्षात्कार सवाल यह है, पहली बात मैं जोर से बोलना चाहते हैं (शून्य वास्तविक विचार के साथ) यह है: रिकर्सिवली पूरे द्विआधारी पुनरावृति और और सबसे छोटा तत्व हैं। यह द्विआधारी पेड़ से बाहर निकालें। अब, इस प्रक्रिया को जहां पूरे पेड़ पुनरावृति और सबसे छोटा तत्व को खोजने के दोहराए जाते हैं, और (पिछले तत्व नए नोड के बाएं बच्चे बनने के साथ) पाया पिछले तत्व के एक माता पिता के रूप में जोड़ें। आवश्यक के रूप में जब तक मूल वृक्ष रिक्त है के रूप में कई बार दोहराएँ। एक लिंक्ड सूची - अंत में, आप सबसे खराब संभव क्रमबद्ध द्विआधारी पेड़ के साथ छोड़ दिया जाता है। आपका सूचक रूट नोड है, जो सबसे बड़ा तत्व है की ओर इशारा करते है।
यह एक भयानक एल्गोरिथ्म ऑल-अराउंड - O (n ^ 2) सबसे खराब संभव द्विआधारी पेड़ उत्पादन के साथ समय से चल रहा है, लेकिन यह कुछ बेहतर के साथ आने से पहले एक सभ्य प्रारंभिक बिंदु है और आप के लिए कोड लिखने के लिए सक्षम होने का लाभ दिया है किसी व्हाइटबोर्ड पर के बारे में 20 लाइनों में यह।
आप पर जाने के लिए ज्यादा देना नहीं है, लेकिन अगर आवश्यकता है कि मैं क्या लगता है कि यह है है, तो आप एक द्विआधारी पेड़ पहले से ही बनाया है और स्मृति में बैठे, लेकिन हल नहीं (जिस तरह से आप चाहते हैं कि उसे क्रमबद्ध करना, वैसे भी) है।
मुझे लगता है कि पेड़ नोड्स की तरह लग रहे संभालने कर रहा हूँ
struct tree_node {
struct tree_node * left;
struct tree_node * right;
data_t data;
};
मैं भी यह सोचते हैं रहा हूँ कि आप सी पढ़ सकते हैं
जब तक हम सिर्फ क्यों इस पेड़ कभी बिना होने क्रमबद्ध आदेश है कि हम किसी भी अच्छे नहीं करता है में बनाया गया बनाया गया था सोच के आसपास बैठते हैं, तो हो सकता है कि मैं इसे पर ध्यान नहीं देंगे और बस छँटाई के साथ सौदा।
आवश्यकता यह है कि बिना किसी अतिरिक्त अंतरिक्ष में इस्तेमाल किया जा अजीब है। अस्थायी रूप से वहाँ अतिरिक्त स्थान, अगर केवल ढेर पर होगा। मुझे लगता है करने के लिए इसका मतलब है कि कि malloc या ऐसा ही कुछ बुला लिए जा रहा हूँ और जिसके परिणामस्वरूप पेड़ मूल अवर्गीकृत पेड़ से अधिक नहीं स्मृति का उपयोग करना पड़ता है भी कि।
पहला और सबसे आसान समाधान है कि पेड़ से प्रत्येक नोड को निकालकर एक नया पेड़ में एक क्रमबद्ध प्रविष्टि कर अवर्गीकृत पेड़ की एक अग्रिम आदेश ट्रावर्सल करना है। यह O (n + n है लॉग इन करें (एन)) है, जो हे है (एन लॉग इन करें (एन))।
यदि यह नहीं है कि वे क्या चाहते हैं और आप रोटेशन और सामान का उपयोग करने के लिए जा रहे हैं ..... कि भयानक है!
मैंने सोचा था कि आप एक ढेर तरह का एक अजीब संस्करण करके ऐसा कर सकते हैं, लेकिन मैं समस्याओं में भाग गया। एक और बात जो मन में आया था, जो बुरी तरह धीमी गति से हो सकता है, पेड़ पर बुलबुला तरह का एक अजीब संस्करण बनाना होगा।
के लिए यह प्रत्येक नोड तुलना में है और संभवतः इसे से प्रत्येक के साथ बदली प्रत्यक्ष बच्चों (और इसलिए अपने माता पिता के साथ भी) है बार-बार जब तक आप पेड़ पार और किसी भी जरूरत स्वैप नहीं पाते हैं। एक शेकर प्रकार (बुलबुला तरह है कि दाएं और बाएं के लिए बाएं जाता है) इस के संस्करण कर सबसे अच्छा काम करेगा, और प्रारंभिक पास करने के बाद आप subtrees कि सम्मान के साथ आदेश से बाहर मुड़कर नहीं देखा नीचे पार करने के लिए उसे अपने जनक है की जरूरत नहीं होगी ।
मुझे यकीन है कि या तो इस algorthm मेरे सामने किसी और के द्वारा सोचा गया था और एक शांत नाम है कि मैं सिर्फ पता नहीं है, है कर रहा हूँ या यह किसी तरह से है कि मैं नहीं दिखाई दे रही है में मौलिक रूप से दोषपूर्ण है।
दूसरा सुझाव के लिए रन-टाइम गणना के साथ आ एक बहुत जटिल है। पहले तो मैंने सोचा कि यह बस हे होगा (एन ^ 2), बुलबुला और शेकर प्रकार की तरह है, लेकिन मैं अपने आप को संतुष्ट नहीं कर सकते कि सबट्री ट्रेवर्सल परिहार (एन पर्याप्त यह एक छोटा सा हे की तुलना में बेहतर बनाने के लिए जीतने के लिए नहीं हो सकता है ^ 2)। अनिवार्य रूप से बुलबुला और शेकर प्रकार इस अनुकूलन भी मिलता है, लेकिन केवल समाप्त हो जाती है, जहां कुल sortedness जल्दी होता है पर और आप सीमा नीचे काट कर सकते हैं। इस पेड़ संस्करण के साथ आप oppurtunities मिल संभवतः सेट के बीच में हिस्सा से बचने के लिए और साथ ही। खैर, जैसे कि मैंने कहा, यह शायद घातक रूप से त्रुटिपूर्ण है।
द्विआधारी पेड़ के ट्रेवर्सल inorder करो और परिणाम की दुकान। आदेश रूट के रूप में क्रमबद्ध सूची के बीच तत्व लेने के द्वारा द्विआधारी खोज वृक्ष के रूप में acending में परिणाम (इस द्विआधारी खोज का उपयोग किया जा सकता है) को सॉर्ट। इसलिए हम संतुलित द्विआधारी खोज वृक्ष मिलता है।
निम्नलिखित कलन विधि समाधान तक पहुँचने के लिए है।
1) किसी भी स्थान का उपयोग किए बिना आदेश उत्तराधिकारी में पाते हैं।
Node InOrderSuccessor(Node node)
{
if (node.right() != null)
{
node = node.right()
while (node.left() != null)
node = node.left()
return node
}
else
{
parent = node.getParent();
while (parent != null && parent.right() == node)
{
node = parent
parent = node.getParent()
}
return parent
}
}
2) आदेश ट्रावर्सल में अंतरिक्ष का उपयोग किए बिना न करें।
क) inorder ट्रावर्सल के पहले नोड का पता लगाएं। यह पेड़ से ज्यादातर बच्चे सही बच्चे ही छोड़ दिया जाना चाहिए अगर यह है, या पहले सही बच्चे के लिए छोड़ दिया है, तो यह है, या। ख) प्रथम नोड के उत्तराधिकारी inoder जानने के लिए एल्गोरिथ्म ऊपर का प्रयोग करें। ग) सभी लौट आए उत्तराधिकारी के लिए दोहराएँ चरण 2।
2 एल्गोरिथ्म ऊपर का प्रयोग करें और अतिरिक्त स्थान का उपयोग किए बिना द्विआधारी पेड़ पर आदेश ट्रावर्सल में करते हैं। द्विआधारी खोज वृक्ष फार्म जब ट्रेवर्सल कर। लेकिन जटिलता है O(N2)सबसे खराब स्थिति।
तरह पेड़ .. nlogn जटिलता ढेर ..
क्रंमोत्तर चंक्रमण करें और उस से एक द्विआधारी खोज वृक्ष पैदा करते हैं।
struct Node * newroot = '\0';
struct Node* PostOrder(Struct Node* root)
{
if(root != '\0')
{
PostOrder(root->left);
PostOrder(root->right);
insertBST(root, &newroot);
}
}
insertBST(struct Node* node, struct Node** root)
{
struct Node * temp, *temp1;
if( root == '\0')
{
*root == node;
node->left == '\0';
node->right == '\0';
}
else
{
temp = *root;
while( temp != '\0')
{
temp1= temp;
if( temp->data > node->data)
temp = temp->left;
else
temp = temp->right;
}
if(temp1->data > node->data)
{
temp1->left = node;
}
else
{
temp1->right = node;
}
node->left = node->right = '\0';
}
}
एक दोगुना जुड़ा हुआ सूची- हे (एन) में inplace किया जा सकता है के लिए बाइनरी ट्री कन्वर्ट
तब तरह यह प्रकार विलय, nlogn का उपयोग कर
सूची एक पेड़ से वापस कन्वर्ट - हे (एन)
सरल nlogn समाधान।
#include <stdio.h>
#include <stdlib.h>
typedef int data_t;
struct tree_node {
struct tree_node * left;
struct tree_node * right;
data_t data;
};
/* a bonsai-tree for testing */
struct tree_node nodes[10] =
{{ nodes+1, nodes+2, 1}
,{ nodes+3, nodes+4, 2}
,{ nodes+5, nodes+6, 3}
,{ nodes+7, nodes+8, 4}
,{ nodes+9, NULL, 5}
,{ NULL, NULL, 6}
,{ NULL, NULL, 7}
,{ NULL, NULL, 8}
,{ NULL, NULL, 9}
};
struct tree_node * harvest(struct tree_node **hnd)
{
struct tree_node *ret;
while (ret = *hnd) {
if (!ret->left && !ret->right) {
*hnd = NULL;
return ret;
}
if (!ret->left ) {
*hnd = ret->right;
ret->right = NULL;;
return ret;
}
if (!ret->right) {
*hnd = ret->left;
ret->left = NULL;;
return ret;
}
hnd = (rand() &1) ? &ret->left : &ret->right;
}
return NULL;
}
void insert(struct tree_node **hnd, struct tree_node *this)
{
struct tree_node *ret;
while ((ret= *hnd)) {
hnd = (this->data < ret->data ) ? &ret->left : &ret->right;
}
*hnd = this;
}
void show(struct tree_node *ptr, int indent)
{
if (!ptr) { printf("Null\n"); return; }
printf("Node(%d):\n", ptr->data);
printf("%*c=", indent, 'L'); show (ptr->left, indent+2);
printf("%*c=", indent, 'R'); show (ptr->right, indent+2);
}
int main(void)
{
struct tree_node *root, *this, *new=NULL;
for (root = &nodes[0]; this = harvest (&root); ) {
insert (&new, this);
}
show (new, 0);
return 0;
}
struct Node
{
int value;
Node* left;
Node* right;
};
void swap(int& l, int& r)
{
int t = l;
l = r;
r = t;
}
void ConvertToBST(Node* n, Node** max)
{
if (!n) return;
// leaf node
if (!n->left && !n->right)
{
*max = n;
return;
}
Node *lmax = NULL, *rmax = NULL;
ConvertToBST(n->left, &lmax);
ConvertToBST(n->right, &rmax);
bool swapped = false;
if (lmax && n->value < lmax->value)
{
swap(n->value, lmax->value);
swapped = true;
}
if (rmax && n->value > rmax->value)
{
swap(n->value, n->right->value);
swapped = true;
}
*max = n;
if (rmax && rmax->value > n->value) *max = rmax;
// If either the left subtree or the right subtree has changed, convert the tree to BST again
if (swapped) ConvertToBST(n, max);
}













