2014-02-27 145 views
0

我有這個代碼的問題。我對C++相當陌生,但其中大部分已經很容易理解。我試圖做一個簡單的鏈接列表數據結構,但是,它打印垃圾而不是列表中的值。我的問題是,我的語法錯在哪裏顯示地址?C++節點和鏈接列表語法

輸出:enter image description here

class Node 
{ 
    public: 
    int data; 
    Node *next; 

    Node(int data) 
    { 
     data = data; 
     next = NULL; 
    }; 
}; 

class LinkedList 
{ 

    Node *first; 
    Node *last; 
    int count; 

public: 
    LinkedList()//constructor for the LinkedList 
    { 
     //initialization 
     first = NULL; 
     last = NULL; 
     count = 0; 
    }; 
    void AddItem(int data) 
    { 
     Node *newItem = new Node(data); 

     if(first == NULL) 
     { 
      first = newItem; 
      last = newItem; 
     } 
     else 
     { 
      Node *traversal = first; 
      while(traversal->next != NULL) 
      { 
       traversal = traversal->next; 
      } 
      traversal->next = newItem; 
      last = traversal->next; 
     } 
     count++; 
    } 

    void DisplayList() 
    { 
     cout<<endl; 
     Node *traversal = first; 
     while(traversal->next != NULL) 
     { 
      cout<<"["<<traversal->data<<"] "; 
      traversal = traversal->next; 

      if(traversal == NULL) 
      { 
       break; 
      } 
     } 
    } 
    bool isEmpty() 
    { 
     if(count < 1) 
     { 
      cout<<"List is empty"; 
      return true; 
     } 
     else 
     { 
      cout<<"List is not empty"; 
      return false; 
     } 
    } 
}; 

int main() 
{ 
cout <<"Linked Lists demo"<<endl; 


LinkedList collection; 
collection.AddItem(1); 
collection.AddItem(3); 
collection.AddItem(5); 
collection.AddItem(7); 
collection.AddItem(9); 
collection.AddItem(11); 
collection.isEmpty(); 
collection.DisplayList(); 
cin.get(); 
+0

請嘗試在運行時嘗試調試並放置斷點以檢查各種分配。 – abnvp

+0

您的成員變量名稱看起來像普通變量名稱,因此您陷入了一個非常常見的陷阱。一個常見的慣例是用m_例如m_data爲成員變量加上前綴。嘗試使用你的代碼,然後檢查Node的構造函數 – kfsone

回答

5
Node(int data) 
{ 
    data = data; // <-- incorrect 
    next = NULL; 
}; 

您還沒有分配輸入參數Node::data成員。您正在將輸入參數分配給自己,使Node::data成員初始化,並使用用於分配新Node的內存塊中已存在的任何隨機值。由於輸入參數具有相同的名稱作爲成員,您需要使用this->data = data代替:

Node(int data) 
{ 
    this->data = data; 
    next = NULL; 
}; 

否則命名的輸入參數,以便它有一個不同的名稱:

Node(int value) 
{ 
    data = value; 
    next = NULL; 
}; 

而且,由於你的列表具有last會員,您可以極大簡化AddItem()實現,你並不需要遍歷所有列表(這需要很長的時間,如果列表中有很多項目在它):

void AddItem(int data) 
{ 
    Node *newItem = new Node(data); 

    if (first == NULL) 
     first = newItem; 

    if (last != NULL) 
     last->next = newItem; 
    last = newItem; 

    ++count; 
} 
+0

或者更好的是,按照日常慣例爲成員加上「m_」,例如「m_data」(同樣,s_代表靜態代碼,g_代表全局變量) – kfsone

+1

@kfsone:我認爲它是更好的,據我所知主要在MFC中是常見的,並且(幸好)已經被淘汰,因爲MFC的優越替代品已經被接管。 –

+0

@JerryCoffin你在考慮匈牙利符號;成員變量前綴(或後綴)不是匈牙利符號(既不是應用程序也不是系統)。如果有的話,[mgs] _前綴是可以接受的,儘管其他常用的替代方法是「mData」,「_data」和「data_」。沒有這樣的區分,你必須更有意識地針對可變陰影進行編碼,例如,在任何地方使用「this-> member」或重命名函數參數名稱。匈牙利人向你提供現代IDE給你的信息;前綴基本上是一種名稱空間的形式。 – kfsone

0

它正在打印垃圾值不是地址,在您的AddItem方法您沒有更新節點的數據。加入此行,將工作

newItem->data=data 
0

更改構造函數:

Node(int d) 
{ 
    data = d; //data = data is wrong 
    next = NULL; 
} 
0

您還可以使用

Node(int data) 
{ 
    Node::data = data; 
    next = NULL; 
}; 

初始化data這是Node類的成員變量。

4

你已經得到了一些答案,但他們似乎都給出了相同的(壞)建議。

而是改變data = data;喜歡的東西this->data = data;的,你應該使用一個成員初始化列表:

Node (int data) : data(data), next(nullptr) {} 

就個人而言,我可能會改變這種狀況遠一點,允許指定「下一個」元素爲節點還有:

Node(int data, Node *next=nullptr) : data(data), next(next) {} 

的構造函數體內部,使用裸名存實亡的參數是可見的,所以data = data;剛分配的參數值回發到自身。在成員初始值列表中,編譯器更聰明(可以這麼說),並且「知道」哪個data是哪個,即使它們具有相同的名稱,也會將參數data中的值分配給成員data(同樣與next )。

順便說一句:儘管有一個空的身體可能最初看起來有點奇怪,你應該習慣它。我猜想我寫的大部分文章都是空的。

另一個(或多或少無關)題外話:我還定義了NodeLinkedList類中(也可能使它private)。除了LinkedList本身,什麼都不需要知道Node類。

+0

'但他們都似乎給了相同(壞)的建議。真正。我有罪。 +1 – axiom

+0

我選擇了第一個答案作爲答案,因爲它解決了我的問題。但是,您的解決方案的工作原理也相同,語法更易於查看。謝謝。 –