2012-04-10 16 views
10

मैं एक सहायक समारोह, copyList नामित लागू करने के लिए, एक पैरामीटर, एक ListNode के लिए सूचक होने की जरूरत है। इस फ़ंक्शन को मूल लिंक्ड सूची की एक प्रति के पहले नोड में पॉइंटर वापस करने की आवश्यकता है। इसलिए, दूसरे शब्दों में, मुझे सी ++ में एक फ़ंक्शन को कोड करने की आवश्यकता है जो एक लिंक्ड सूची का हेडर नोड लेता है और पूरी लिंक्ड सूची की प्रतिलिपि बनाता है, जो नए हेडर नोड में पॉइंटर लौटाता है। मुझे इस समारोह को लागू करने में मदद की ज़रूरत है और यह मेरे पास अभी है।एक समारोह कोडिंग सी में किसी लिंक किए गए-सूची की प्रतिलिपि करने के ++

struct Listnode {  
    Student *student; 
    Listnode *next; 
}; 

नोट:: एक और पहलू है कि मैं इस समारोह के साथ में चल रहा एक स्थानीय चर के लिए सूचक लौटने का विचार है

Listnode *SortedList::copyList(Listnode *L) { 

    Listnode *current = L; //holds the current node 

    Listnode *copy = new Listnode; 
    copy->next = NULL; 

    //traverses the list 
    while (current != NULL) { 
     *(copy->student) = *(current->student); 
     *(copy->next) = *(current->next); 

     copy = copy->next; 
     current = current->next; 
    } 
    return copy; 
} 

इसके अलावा, इस Listnode संरचना के साथ मैं काम कर रहा हूँ है।

+3

+1 एक अच्छी तरह से प्रस्तुत प्रश्न के लिए! पहला काउंटर-प्रश्न: क्या आप एक एकल नोड आवंटित करके एक संपूर्ण सूची कॉपी कर सकते हैं? दूसरी, तीसरी, ... और nth नोड सामग्री की प्रतियां कहाँ संग्रहित की जाएंगी? –

+0

धन्यवाद, मुझे यकीन नहीं है कि क्या मैं आपके सवालों का पूरी तरह उत्तर दे रहा हूं लेकिन मैं अपना सर्वश्रेष्ठ प्रयास करूंगा: - मुझे सूची की पूरी तरह से नई प्रतिलिपि बनाना है। इसलिए, मैं हेडर नोड की प्रतिलिपि नहीं बना सकता क्योंकि मेरी प्रतिलिपि सूची में वही संदर्भ होंगे। मैं सिर्फ मूल्यों की प्रतिलिपि बनाना चाहता हूं। - साथ ही, प्रतिलिपि सूची में पहली सूची नोड में मूल सूची में पहली सूची नोड के समान मान होना चाहिए। लेकिन कॉपी की गई सूची को मूल सूची में किसी भी नोड्स को संदर्भित/इंगित नहीं करना चाहिए। –

+1

नई सूची को पुराने किसी भी एनओडीईएस को इंगित नहीं करना चाहिए, लेकिन नए नोड्स पुराने सामग्री को इंगित करना चाहिए? इस मामले में "सामग्री" वस्तुएं "छात्र" वस्तुएं हैं। असल में, क्या आप छात्रों को भी कॉपी कर रहे हैं? सवाल में यह स्पष्ट नहीं है। तो दो सूचियां एक ही छात्र को इंगित कर सकती हैं, लेकिन अलग-अलग सूचियां हो सकती हैं, या प्रत्येक सूची छात्रों की अपनी प्रतियों के "स्वामित्व" भी हो सकती है। –

उत्तर

5

पहला सवाल आप अपने आप को पूछने की आवश्यकता क्या प्रतिलिपि अर्थ विज्ञान हो रहा है। विशेष रूप से, आप Student* नोड सामग्री के रूप में उपयोग कर रहे हैं। नोड सामग्री की प्रतिलिपि क्या मतलब है?क्या हमें सूचक की प्रतिलिपि बनाना चाहिए ताकि दोनों सूचियां एक ही छात्र उदाहरणों को इंगित करें (साझा करें), या आप deep copy कर सकते हैं?

struct Listnode {  
    Student *student; // a pointer? shouldn't this be a `Student` object? 
    Listnode *next; 
}; 

अगला प्रश्न आपको खुद से पूछना चाहिए कि आप दूसरी सूची के लिए नोड्स कैसे आवंटित करेंगे। वर्तमान में, आप प्रतिलिपि में केवल 1 नोड आवंटित करते हैं।

मुझे लगता है कि आप कोड अधिक तरह दिखना चाहिए:

Listnode *SortedList::copyList(Listnode *L) { 

    Listnode *current = L; 

    // Assume the list contains at least 1 student. 
    Listnode *copy = new Listnode; 
    copy->student = new Student(*current->student); 
    copy->next = NULL; 

    // Keep track of first element of the copy. 
    Listnode *const head = copy; 

    // 1st element already copied. 
    current = current->next; 

    while (current != NULL) { 
     // Allocate the next node and advance `copy` to the element being copied. 
     copy = copy->next = new Listnode; 

     // Copy the node contents; don't share references to students. 
     copy->student = new Student(*current->student); 

     // No next element (yet). 
     copy->next = NULL; 

     // Advance 'current' to the next element 
     current = current->next; 
    } 

    // Return pointer to first (not last) element. 
    return head; 
} 

आप दो सूचियों के बीच छात्र उदाहरणों को साझा करने को प्राथमिकता देते हैं, तो आप

copy->student = current->student; 
बजाय

copy->student = new Student(*current->student); 
उपयोग कर सकते हैं
0

कथन copy->next = current->next गलत है। आप

Create the first node copy here 
copy->student = current->student; 
copy->next = NULL; 
while(current->next!=NULL) 
{ 
    Create new node TEMP here 
    copy->next = TEMP; 
    TEMP->student = current->student; 
    TEMP->next = NULL; 
    copy = TEMP; 
} 
0

करना चाहिए जब से तुम लिंक्ड सूची की एक प्रति की जरूरत है, आप पाश में एक नया नोड बनाने के लिए है, जबकि मूल सूची के माध्यम से traversing की जरूरत है।

Listnode *startCopyNode = copy; 

while (current != NULL) { 
    *(copy->student) = *(current->student); 
    copy->next = new Listnode; 
    copy = copy->next; 
    current = current->next; 
} 

copy->next = NULL; 
return startCopyNode; 

delete लिंक की गई सूची के नोड्स को याद रखें।

2

यह उत्कृष्ट प्रश्न है क्योंकि आपने अपने काम का बड़ा हिस्सा किया है, "कृपया मेरे लिए अपना होमवर्क करें" प्रश्नों से कहीं अधिक बेहतर है।

कुछ अंक।

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

दूसरे, आप केवल प्रति सूची में पहले नोड का आवंटन, आप मूल सूची में नोड प्रति एक करने की ज़रूरत है।

कुछ की तरह (छद्म कोड (लेकिन सी ++ - होमवर्क के लिए की तरह), खेद):

# Detect empty list early. 

if current == NULL: 
    return NULL; 

# Do first node as special case, maintain pointer to last element 
# for appending, and start with second original node. 

copy = new node() 
last = copy 

copy->payload = current->payload 
current = current->next 

# While more nodes to copy. 

while current != NULL: 
    # Create a new node, tracking last. 

    last->next = new node() 
    last = last->next 

    # Transfer payload and advance pointer in original list. 

    last->payload = current->payload 
    current = current->next 

# Need to terminate new list and return address of its first node 

last->next = NULL 
return copy 

और, जब तुम सही है कि आप एक स्थानीय ढेर चर के लिए सूचक वापस नहीं करना चाहिए रहे हैं, आप क्या कर रहे हैं। वेरिएबल जो आप हैंड-आवंटित मेमोरी पर पॉइंट लौट रहे हैं, जो फ़ंक्शन से बाहर निकलेंगे।

0

@pat, मुझे लगता है क्योंकि आप स्मृति केवल एक बार बनाने यदि आप एक seg_fault मिल जाएगा। आपको प्रत्येक नोड के लिए स्मृति बनाने की आवश्यकता है (मूल रूप से 'नया')। सभी नोड्स के लिए मेमोरी बनाने के लिए, जहां आपको 'नया' कीवर्ड का उपयोग करने की आवश्यकता है, पता लगाएं।

एक बार जब आप इस के साथ किया जाता है, आप पिछले नोड के लिए यह लिंक करने के लिए है, क्योंकि इसकी एक अकेले सूची जुड़ा हुआ है, आप पिछले नोड के लिए एक सूचक बनाए रखने की जरूरत की जरूरत है। यदि आप सीखना चाहते हैं और पूरे जीवन को याद रखने में सक्षम होना चाहिए, तो ऊपर वर्णित किसी भी कोड को न देखें। उपर्युक्त कारकों को सोचने का प्रयास करें और अपने कोड के साथ आने का प्रयास करें।

0

जैसा कि अन्य लोगों के पास है बाहर inted, आप मूल सूची में प्रत्येक नोड के लिए new कॉल करने के लिए की नकल की नोड में एक प्रति के लिए जगह आवंटित करने के लिए, और फिर नया करने के लिए पुराने नोड को कॉपी करें और अद्यतन सूचक की जरूरत है।

एक अन्य कारक जो मैं इस फ़ंक्शन के साथ चल रहा हूं वह एक स्थानीय चर के लिए सूचक को वापस करने का विचार है।

आप एक स्थानीय चर के लिए एक सूचक वापस नहीं कर रहे हैं; जब आप new कहा जाता है, आप ढेर पर स्मृति आवंटित और कहा कि (जो निश्चित रूप से आप समारोह के बाहर यह मुक्त करने के लिए जब आप नई सूची से किया जाता है से, delete कॉल करने के लिए याद करने की आवश्यकता है कि इसका मतलब है) के लिए एक सूचक लौट रहे हैं ।

1

मैं एक ही बात करने के लिए कोशिश कर रहे हैं। मेरे आवश्यकताएं थीं:

1. प्रत्येक नोड एक बहुत ही बुनियादी और सरल वर्ग (मैं struct मॉडल से दूर चले गए) है।
2. मैं एक गहरी प्रतिलिपि बनाना चाहते हैं, और न सिर्फ पुराने लिंक्ड सूची के लिए सूचक।

तरह से है कि मैं यह करने के लिए चुना है निम्नलिखित सी ++ कोड के साथ है:

template <class T> 
Node <T> * copy(Node <T> * rhs) 
{ 
    Node <T> * current = new Node<T>(); 
    Node <T> * pHead = current; 
    for (Node <T> * p = rhs; p; p = p->pNext) 
    { 
     Node <T> * prev = current; 
     prev->data = p->data; 
     if (p->pNext != NULL) 
     { 
      Node <T> * next = new Node<T>(); 
      prev->pNext = next; 
      current = next; 
     } 
     else 
     { 
      prev->pNext = NULL; 
     } 
    } 
    return pHead; 
} 

यह कोई त्रुटियों के साथ अच्छी तरह से काम करता है। चूंकि "हेड" एक विशेष मामला है, इसलिए "वर्तमान" सूचक के कार्यान्वयन की आवश्यकता है।

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