2010-05-31 81 views
0

我想按鏈接列表中的字母順序排列名稱,但得到運行時錯誤。我在這裏做錯了什麼?排序鏈接列表中的名稱

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

struct node{ 
    string name; 
    node *next; 
}; 

node *A; 

void addnode(node *&listpointer,string newname){ 
    node *temp; 
    temp = new node; 
    if (listpointer == NULL){ 
     temp->name = newname; 
     temp->next = listpointer; 
     listpointer = temp; 
    }else{ 
     node *add; 
     add = new node; 
     while (true){ 
      if(listpointer->name > newname){ 
       add->name = newname; 
       add->next = listpointer->next; 
       break; 
      } 
      listpointer = listpointer->next; 
     } 
    } 
} 

int main(){ 

    A = NULL; 
    string name1 = "bob"; 
    string name2 = "tod"; 
    string name3 = "thomas"; 
    string name4 = "kate"; 
    string name5 = "alex"; 
    string name6 = "jimmy"; 
    addnode(A,name1); 
    addnode(A,name2); 
    addnode(A,name3); 
    addnode(A,name4); 
    addnode(A,name5); 
    addnode(A,name6); 

    while(true){ 
     if(A == NULL){break;} 
     cout<< "name is: " << A->name << endl; 
     A = A->next; 
    } 

    return 0; 

} 
+0

爲什麼你的代碼中沒有一個而是兩個*無限循環? – 2010-05-31 04:35:58

+0

你也有一個很好的內存泄漏,在'listpointer'不爲NULL的情況下'temp'被創建,但未被使用(並且因此不可能被釋放)在'addnode'中。 – 2010-05-31 04:38:07

回答

1

我認爲錯誤是,你認爲:

if (listpointer == NULL){ 
    temp->name = newname; 
    temp->next = listpointer; 
    listpointer = temp; 
} 

保證listpointer永遠不會爲NULL後。然而,這是不是這樣的,例如:

void addnode(node *&listpointer,string newname){ 
    node *temp; 
    temp = new node; 
    if (listpointer == NULL){ 
     temp->name = newname; 
     temp->next = listpointer; 
     listpointer = temp; 
    }else{ 
     node *add; 
     add = new node; 
     while (true){ 
      if((listpointer) == NULL){ 
      std:cout << "oops (listpointer) == NULL)"; 
      } 

      if(listpointer->name > newname){ 
       add->name = newname; 
       add->next = listpointer->next; 
       break; 
      } 
      listpointer = listpointer->next; 
     } 
    } 
} 

會打印出「糟糕」則作爲段錯誤是lispointer NULL和使用 - >對NULL會導致段錯誤。這是因爲在while(true)循環中,列表指針最終到達最後並被設置爲NULL。你然後得到段錯誤。

我想一個更好的想法是做類似:

bool has_inserted; 
while (listpointer != NULL){ 
    if(listpointer->name > newname){ 
    add->name = newname; 
    add->next = listpointer->next; 
    has_inserted = true; 
    break; 
    } 
    listpointer = listpointer->next; 
} 
if(has_inserted == false){ 
//insert at end of list 
} 

而且這個代碼泄漏內存,你不刪除你創建新的東西。你可能想用valgrind運行這個(和其他代碼)來看看我的意思。從你的代碼刪除臨時從內存泄漏防止 -

1:

4

您試圖取消引用addnode中的空指針。在listpointer->name > newname從不爲真的情況下,listpointer最終將被設置爲NULL,然後在接下來的listpointer->name > newname比較中嘗試再次解除引用。

...代碼中的其他可能的邏輯錯誤,也就是說。

0

我做你的代碼進行一些修改。

2 - 您必須保持列表的第一個元素的指針。如果你失去了它,你將無法再添加更多的項目或打印列表內容。

3 - 代碼必須分析是否必須將新項目插入列表的頂部,中間或末尾。如果在頂部,則列表指針必須更改爲它。

所以我修復了這個bug,你的代碼現在已經很好了。

請記住,您的main()應該調整爲在打印其項目時不更改列表指針(A)。如果是這樣,打印後您將失去對列表的控制權,並且無​​法再訪問或刪除其節點。如果你在這個測試中不關心它,就忘記它。

void addnode(node *&listpointer,string newname){ 
    node *add, 
     *last, 
     *current; 

    add = new node; 
    add->name = newname; 

    if (listpointer == NULL){ 
     add->next = listpointer; 
     listpointer = add; 
    }else{ 
     current = listpointer; 
     last = listpointer; 
     while (current && current->name < newname){ 
      last = current; 
      current = current->next; 
     } 

     if (current == listpointer){ 
      /* Insert before 1st node */ 
      add->next = listpointer; 
      listpointer = add; 
     } 
     else{ 
      /* Insert between last and current 
       or at the end of the list */ 
      last->next = add; 
      add->next = current; 
     } 
    } 
}