2014-11-24 93 views
1

在此代碼:爲什麼我需要在修改鏈接列表時分配給指向鏈接列表的指針?

void push(node **head, int data) { 
    node *temp = malloc(sizeof(node)); 
    temp->data = data; 
    temp->next = *head; 
    *head = temp; 
} 

爲什麼temp->next = *head還不夠嗎?

爲什麼需要設置*head等於temp?那完成了什麼呢?

+0

考慮到這一點,您創建了一個應該成爲下一個頭的節點。但最後如果你遺漏了這個任務,那麼會指向什麼呢? – 2014-11-24 22:45:33

回答

2

方法push()有兩個參數:指向指向node(它是指向鏈接列表的指針)的指針以及要插入列表的值。

爲什麼*head = temp;是必要的,以便調用者的鏈表最終得到修改。沒有這一行,調用者的鏈表不會被修改。

這是爲什麼這是必要的一個非常簡化的例子。比方說,我有一個修改一個int的方法:

void foo(int *bar) { 
    int baz; 
    baz = *bar; 
    baz = 42; 
} 

我通過傳遞指針調用foo()後,什麼都不會發生指針所指向的變量。當foo()完成時,所有堆棧變量(即barbaz)將不存在,並且對bar值的修改從不保存)。

回到你的問題中的例子。如果該行永遠不會被調用,沒有任何會發生在調用者的副本中(即在調用該函數後,就好像該元素從未添加到列表中),原因與調用者傳入的副本相同foo()沒有改變。

出於這個原因,你經常看到的insert()功能的不同方法簽名:

node *push(node *head, int data); 

調用此方法是這樣的:

// assume head is a pointer to a node 
head = push(head, 42); 

的效果是一樣的,但是因爲有隻一個指向節點的指針傳入,無論push()對列表的結構做什麼,都不會應用到head,直到分配發生。

+0

答案很公平,謝謝大家的關注,尤其是關於node * push()的最後一部分已經澄清。 – 2014-11-24 23:01:05

1

它重置頭部到新節點,允許我們迭代所有元素。 Push將新節點放置在列表的開頭。 Head就像是一個鏈接列表的出發點,通過它可以獲得所有元素。如果頭部未設置爲新節點,則將丟失對新插入的數據的引用,從而導致內存泄漏。

0

假設它是一個基於列表的堆棧(基於Push操作進行猜測),那麼應該將該項添加到列表的開頭,以便它可以很容易地彈出。 這樣,當調用者再次嘗試使用堆棧時,列表頭將使用新的數據項更新。