यह बहुत संभव है। मैं ऐसे समाधान के साथ आया जो संभवतः इष्टतम नहीं है लेकिन दिखाता है कि यह किया जा सकता है। सबसे पहले इसे दो समस्याओं में विभाजित करें: अगले पॉइंटर्स को उलटकर और यादृच्छिक पॉइंटर्स को उलट दें।
पीछे अगला संकेत:
node* last = NULL;
node* current = head;
node* next = head->next;
while (current != NULL)
{
current->next = last;
last = current;
current = next;
if (current != NULL)
next = current->next;
}
head = last
यादृच्छिक सूची पीछे थोड़ा जटिल काम है, सिर्फ इसलिए कि हम यादृच्छिक सूचक चेन के प्रमुखों के सभी की एक सूची नहीं है, लेकिन हम की छोर पा सकते हैं उन्हें (नोड्स एक पूर्ण यादृच्छिक सूचक होगा)। इसे करने के लिए हमें कई सहायक कार्यों की आवश्यकता होगी। सबसे पहले एक यादृच्छिक सूची को उलट करने के लिए एक है। हम बड़े पैमाने पर ऊपर से कोड कॉपी करते हैं। ध्यान दें कि हम एक विशेष मूल्य होने के लिए श्रृंखला का अंत निर्धारित कर रहे हैं। यह हमें एक सूची को फिर से बदलने से रोकता है। स्पष्टीकरण के लिए टिप्पणियों में चर्चा देखें।
node* chainTail = malloc(1); //mallocing here to get a unique pointer
void reverseRandom(node* rhead)
{
node* last = chainTail;
node* current = rhead;
node* next = rhead->random;
while (current != NULL)
{
current->random = last;
last = current;
current = next;
if (current != NULL)
next = current->random;
}
}
हम भी एक सहायक समारोह जरूरत है एक नोड के माता-पिता को खोजने के लिए (या शून्य वापसी अगर वहाँ कोई है)। अब
node* findParent(node* target)
{
node* candidate = head;
while ((candidate != NULL) && (candidate->random != target))
candidate = candidate->next;
return candidate;
}
हम सिर्फ सूची चलना, किसी भी नोड्स NULL (हमारे श्रृंखला पूंछ) के एक यादृच्छिक मूल्य है मिल जाए, उनके श्रृंखला सिर मिल जाए, और चेन रिवर्स:: हम एक गूंगा रैखिक खोज करेंगे
node* current = head; //Current node in a linear walk looking for chain tails
while (current != NULL)
{
if (NULL == current->random)
{
//current is the tail of a random chain, lets find the head
node* curr = current; //Current node in the search for the chain hean
node* parent = findParent(curr);
while (parent != NULL)
{
curr = parent;
parent = findParent(curr);
}
//At this point, curr is the head of the random chain, so reverse it
reverseRandom(curr);
}
current = current->next;
}
//Clean up chainTail pointers
node* current;
for (current = head; current != NULL; current = current->next)
{
if (current->random == chainTail)
{
current->random = NULL;
}
}
free(chainTail); //Stop a memory leak if this is not a global
मानक अस्वीकरण: मैंने यह कोड नहीं चलाया है। इसमें बग हो सकती है। मुझे अंत के करीब नींद आना शुरू हो गया, इसलिए मैंने एक तार्किक त्रुटि की हो सकती है, लेकिन ऐसा लगता है कि मुझे काम करना है।
इसके अलावा, यदि आप इसे उत्पादन में डाल रहे हैं, तो नहीं। यह कोड ओ (एन^3) के आसपास कहीं चलाता है। यह सबसे तेज़ समाधान नहीं है। यह स्थिर स्थान का उपयोग करता है (हालांकि यहां तक कि शायद इन-अस्तर और आक्रामक परिवर्तनीय साझाकरण द्वारा भी कम किया जा सकता है)।
उत्तर के लिए धन्यवाद। लेकिन, मेरे पास सिर्फ एक मुद्दा है .. आप एक यादृच्छिक श्रृंखला को फिर से उलटने से कैसे बचते हैं? मान लें कि आपने एक यादृच्छिक श्रृंखला को उलट दिया है जिसे आपने मुख्य सूची की शुरुआत में कहीं भी देखा था। बाद में, जब आप मुख्य सूची को पार करते हैं, तो आपने एक नोड मारा जो पहले से ही यादृच्छिक श्रृंखला का सदस्य था जिसे आप पहले ही उलट चुके थे .. ऐसा करने के लिए, आपको अतिरिक्त बुकिपींग की आवश्यकता है .. आप अतिरिक्त संग्रहण के बिना इसका ट्रैक कैसे रखते हैं? –
@arun_suresh आप सही हैं कि डबल रिवर्सल का खतरा है, लेकिन जहां आप इसकी अपेक्षा नहीं करते हैं। अगला पॉइंटर रिवर्सल ठीक है क्योंकि आप केवल पहले फंक्शन में अगले पॉइंटर्स को उलट देते हैं। आप यादृच्छिक पॉइंटर्स को पीछे छोड़ दें और अगले पॉइंटर्स को अकेले छोड़ दें, इसलिए क्रॉस दूषित होने का कोई खतरा नहीं है। इसके अलावा, चूंकि कोई भी दो नोड्स एक ही यादृच्छिक सूचक को इंगित करता है, यह भी सुरक्षित है। एकमात्र जोखिम यह है कि एक श्रृंखला का सिर पूंछ की तुलना में सूची में आगे है, इसलिए जब हम नई पूंछ को दबाते हैं तो हम पूंछ को फिर से मारते हैं और फिर हम इसे उलट देते हैं। –
ठीक है, हाँ, सरल समाधान: नई श्रृंखला पूंछ अंत नल के साथ नहीं है, लेकिन एक विशेष मूल्य के साथ और फिर उन्हें उलट करने के बाद उन्हें साफ़ करें। मैं सवाल संपादित करूंगा। –