2013-12-15 193 views
-2

我必須把這個名爲「reversePrint」的成員函數添加到這個雙向鏈表中。並反向打印出名字。 例如,輸入: 傑森 瑞安 迪倫 路易雙向鏈接列表反向打印?

輸出應該是: 路易 迪倫 瑞安 傑森

我能完成這一操作思路是向下移動一直到結束列表中的第一個,即最後一個節點。然後使用「Previous」指針一次返回到前一個節點,同時打印出名稱。所以我會有一個反轉的印刷。 但是,我的指針有點問題,我想不出如何解決它。一些幫助真的很感謝!

**更新:此代碼最初是單鏈接的。我試圖把它變成雙重鏈接並添加「reversePrint」功能。不過我認爲問題在於,我沒有修改「添加」方法,因此「prev」指針斷開。那麼,如何修改「添加」的任何幫助,使我可以成爲一個完全雙向鏈表?

這是它現在給出的輸出: 分組爲0x0 地址0x100200000數據的 下一0x100300000

分組爲0x0 地址0x100300000數據B 下0x100400000

分組爲0x0 地址0x100400000數據c next 0x0

這是我們需要的輸出: prev 0x0 個地址0x100200000數據 下一0x100300000

分組0x100200000 地址0x100300000數據B 未來0x100400000

分組0x100300000 地址0x100400000數據c 未來爲0x0

以下是我的代碼:

#include <iostream> 
    #include <string> 
    using namespace std; 

    // define a node for storage and linking 
    class node{ 
    public: 
     string name; 
     node *next; 
     node *prev; // to be implemented by students 
    }; 

    class linkedList{ 
    public: 
     linkedList():top(NULL){} 
     bool empty(){return top == NULL;} 
     node *getTop(){return top;} 
     void setTop(node *n){top = n;} 
     void add(string); 
     int menu(); 
     void remove(string); 
     ~linkedList(); 
     void reversePrint(); // to be implemented by students 
     friend ostream& operator << (ostream&, const linkedList&); // default output is in-order print. 
    private: 
     node *top; 
     node *end; // to be used for reverse print and implemented by students 
    }; 

    int main(void){ 
     linkedList l; 
     //cout << l.empty() << endl; 
     int option = 0; 
     string s; 
     bool go = true; 
     while(go){ 
      option = l.menu(); 
      switch(option){ 
       case 1: cout << "enter a name: ";cin >> s; l.add(s); break; 
       case 2: cout << "enter name to be deleted: "; cin >> s; l.remove(s);break; 
       case 3: cout << l; break; 
       case 4: l.reversePrint(); break; 
       case 5: cout << "exiting" << endl; go = false; break; 
      } 
     } 
     // l goes out of scope and calls ~linkedList() 
     return(NULL); 
    } 
    // can not call this method "delete" - "delete" is a reserved keyword. 
    void linkedList::remove(string s){ 
     bool found = false; 
     node *curr = getTop(), *prev=NULL; 
     while(curr != NULL){ 
      // match found, delete 
      if(curr->name == s){ 
       found = true; 
       // found at top 
       if(prev == NULL){ 
        node *temp = getTop(); // delete the current node(which is the head), and set the "new head" to as the next node 
        setTop(curr->next); 
        delete(temp); 
        // found in list - not top 
       }else{ 
        prev->next = curr->next; //Skip the current deleted node, connect previous node directly to the next node 
        delete(curr); 
       } } 
      // not found, advance pointers 
      if(!found){ 
       prev = curr; 
       curr = curr->next; } 
      // found, exit loop 
      else curr = NULL; } 
     if(found)cout << "Deleted " << s << endl; 
     else cout << s << " Not Found "<< endl; } 


    void linkedList::add(string s){ 
     node *n = new node(); 
     n->name = s; 
     n->next = NULL; 
     // take care of empty list case 
     if(empty()){ top = n; 
      // take care of node belongs at beginning case 
     } else if(getTop()->name > s) 
     { 
      n->next = getTop(); 
      setTop(n); 
      // take care of inorder and end insert 
     }else{ 
      // insert in order case 
      node *curr = getTop(), *prev = curr; 
      while(curr != NULL){ 
       if(curr->name > s)break; 
       prev = curr; 
       curr = curr->next; 
      } 
      if(curr != NULL){ // search found insert point 
       n->next = curr; 
       prev->next = n; } 
      // take care of end of list insertion 
      else if(curr == NULL){// search did not find insert point 
       prev->next = n; } 
     } } 

    void linkedList::reversePrint(){ 
     node *curr = getTop(), *prev=NULL; 
     // jump to the last node 
     while(curr->next != NULL){ 
      prev = curr; 
      curr = curr->next; 

      //curr = curr->next; 
      cout << "!!!!hahaha" << curr->name <<" Prev:" <<curr->prev << " " << prev->name <<endl ;//testing purpose 

     } 

     //print the name then jump back to the previous node, stops at the first node which curr->prev = NULL 
     while(prev != 0){ 
      cout << "NULL is not 0!"; 
      prev->prev = curr->next; 
      //cout << curr->name; 
      curr = prev; 
     } 


    } 

    /*ostream& operator << (ostream& os, const linkedList& ll){ 
     //linkedList x = ll; // put this in and the code blows up - why? 
     node *n = ll.top; 
     if(n == NULL)cout << "List is empty." << endl; 
     else 
      while(n != NULL){ 
       os << n->name << endl; 
       n = n->next; 
      } return os; 
    }*/ 
    ostream& operator << (ostream& os, const linkedList& ll){ 
     //linkedList x = ll; // put this in and the code blows up - why? 
     node *n = ll.top; 
     if(n == NULL)cout << "List is empty." << endl; 
     else 
      while(n != NULL){ 
       os << " prev " << n->prev << endl; 
       os << " address " << n << " data " << n->name << endl; 
       os << " next " << n->next << endl; 
       n->prev = n; 
       n = n->next; 
      } return os; 
    } 

    // return memory to heap 

    linkedList::~linkedList(){ 
     cout << "~linkedList called." << endl; 
     node *curr = getTop(), *del; 
     while(curr != NULL){ 
      del = curr; 
      curr = curr->next; 
      delete(del); 
     } 
    } 

    int linkedList::menu(){ 
     int choice = 0; 
     while(choice < 1 || choice > 5){ 
      cout << "\nEnter your choice" << endl; 
      cout << " 1. Add a name." << endl; 
      cout << " 2. Delete a name." << endl; 
      cout << " 3. Show list." << endl; 
      cout << " 4. Show reverse list. " << endl; // to be implemented by students 
      cout << " 5. Exit. " << endl; 
      cin >> choice; 
     } 
     return choice; 
    } 
+0

這怎麼可能是你的代碼? – 2013Asker

+1

這就像「正向打印」。只有從「尾巴」(vs.「head」)開始,並通過「previousNode」(與「nextNode」)進行導航。如果這不起作用,則在創建列表時可能沒有正確設置前一個節點指針。 – user2864740

+0

這是個玩笑嗎? –

回答

2

這看起來有問題:

prev->prev = curr->next; 

您正在設置上一個節點的上一個節點。你可能只想設置前一個節點,對吧?

你可能想要做這樣的事情:

while(curr != NULL) 
{ 
    cout << curr->name; 
    curr = curr->prev 
} 

因爲由這點你已經確定curr在列表的最後一個元素,你現在「減」 curr通過分配curr到它的前面可以元件。由於第一個元素沒有前一個節點,因此它是prev將是NULL。這樣,當curr已被分配給第一個元素的前一個元素時,循環將停止,這又是NULL

+0

但是,如果你把它放在並看到輸出,你可以看到,「prev」指針是有點斷開。所以我到達最後一個節點後無法回去。我想我必須修改「Linkedlist :: Add」來將它們鏈接起來? – user3103980

+0

這是正確的。你的add函數應該確保最後添加的節點的'next'和'prev'指針以及新節點指向正確的節點。 – sFuller

1

您的功能添加無效。例如考慮列表爲空時的情況。下面的代碼片段將對應於這種情況。

void linkedList::add(string s){ 
    node *n = new node(); 
    n->name = s; 
    n->next = NULL; 
    // take care of empty list case 
    if(empty()){ top = n; 
     // take care of node belongs at beginning case 
    } else if(getTop()->name > s) 

正如你可以看到沒有設置列表的數據成員末尾。

因此,在編寫函數reversePrint的實現之前,您應該確保函數add能正常工作。

+0

我不明白,它似乎像我們的代碼缺少一些部分。 – user3103980

+0

@ user3103980,我認爲這是你的任務,寫下缺少的代碼。 –

+0

看來你所做的只是簡單地刪除了一些我的代碼。好的非常有幫助。 – user3103980