2013-04-11 35 views
0

我正在處理鏈表的示例。但是,我目前無法理解head_insert方法。請有人解釋一下。謝謝。插入到鏈表頭時混淆了指針

#include <iostream> 
using namespace std; 

struct node_ll 
{ 
    int payload; 
    node_ll* next; // pointer to the next node 
}; 

void head_insert(node_ll** list, int pload) 
{ 
    node_ll* temp = new node_ll;//Declare temp, a pointer to a node. 
    temp->payload = pload;//Set the payload of the struct at the address of temp to pload. 
    temp->next = *list;//Set the next of the struct at the address of temp to the pointer to the old head of the list. 
    *list = temp;//Set the pointer to the old head of the list to the pointer to the temp node. 
    //Why doesnt the temp->next = temp? 
}; 

void print_ll(node_ll** list) 
{ 
    node_ll* temp; 
    temp = *list; 
    while (temp) // != NULL 
    { 
     cout << temp->payload << '\n'; 
     temp = temp->next; 
    }; 
} 

int main() 
{ 
    node_ll* alist = NULL; 
    cout << "Empty list a to start\n"; 
    head_insert(&alist, 2); 
    head_insert(&alist, 4); 
    head_insert(&alist, 6); 
    cout << "List a after head insertion of 2,4,6 is \n"; 
    print_ll(&alist); 
    cout << '\n'; 
    system("PAUSE"); 
    return 0; 
} 

我的困惑在評論中詳細說明。如果我有線條

temp->next = *list; 
*list = temp; 

爲什麼我的新創建的節點指向在明年自己的地址?

+0

我真的不明白你的問題。沒有「清單」作爲可以「指向」任何東西的單一實體; 「列表」由*所有*節點組成。 – 2013-04-11 06:45:56

+0

@KarlKnechtel我糾正了我的錯誤。抱歉。 – 2013-04-11 06:48:14

+0

提示:在* * list = temp'賦值之前指向*的'* list'是什麼? – WhozCraig 2013-04-11 07:10:29

回答

1
//Declare temp, a pointer to a node. 

編號「創建一個新節點,並讓temp爲該節點的地址。」

//Set the payload of the struct at the address of temp to pload. 

號 「設置結構其地址的​​爲temp到PLOAD」。這可能是你的意思,但你確實需要確切地說明這些事情。無論如何,這填寫了我們剛剛創建的新節點的​​。

//Set the next of the struct at the address of temp to the pointer to the old head of the list. 

同樣...「設置結構地址爲temp到的list的老首長的地址的next。」

//Set the pointer to the old head of the list to the pointer to the temp node. 

小心。這是事情:「列表的舊頭的地址」是一個,而不是一個變量。它可以存在於內存中的多個位置,就像4可以存儲在內存中的多個位置一樣。

該功能被給予node_ll**,即(node_ll*)*-指向node_ll*的指針。具體來說,當我們從main調用函數時,我們在當前調用main時給它一個指針給變量a_list

因此,當我們做*list =,我們正在寫內存位置 - 實際上,取代a_list變量。使用這樣的內存地址可以讓我們模擬「通過引用傳遞」並更改來自調用者的變量的值(我們不能只從參數訪問這些變量的值,因爲我們得到了副本;而且我們不能作爲全局變量訪問它們,因爲它們不是全局變量)。

//Why doesnt the temp->next = temp? 

爲什麼會這樣?代碼從上到下運行(儘管有控制結構)。 temp->next被設置爲列表的頭,之前我們設置了新的列表頭。

看起來像你期望的temp->next只是因爲在過程中的那一點,它碰巧指向列表的舊頭,然後我們改變了一個也碰巧具有相同值的變量 - 即,指向列表的老頭。但它們是相當明顯的單獨變量。如果我寫a = 4; a *= 3,值4不會改變;變量a呢。所以它也是指針,他們只是另一種價值。

0

這是令人困惑的代碼。

list指向指向節點的指針的指針。 *list = temp不是更改任何節點,它正在改變傳入的指針,因此它指向插入的節點。

+0

列表是一個指向節點的指針。它是否正確?我認爲**列表是一個指向節點的指針。 – 2013-04-11 06:55:22

+0

我們的參數聲明是'node_ll ** list'。這意味着「list的類型是'node_ll **'」。那麼,這是C++的思考方式。傳統的C思維方式是「**列表的類型是'node_ll'」。但這些*真的意味着同樣的事情*。這是Kernighan和Ritchie的「聰明」概念的人爲因素,它使用相同的符號來表示解引用操作,就像用於首先描述類型一樣。 – 2013-04-11 07:02:56

+0

這並不是真的令人困惑;額外的間接級別是模擬通過引用的標準方式。問題是C有很少的抽象工具,指針可以用於多種用途,有時候你會爲了不同的目的而建立不少用於不同目的的'*',並且沒有明確的方式來表示每個目的的用途。 – 2013-04-11 07:04:34

0

在您的head_insert函數中,新節點被添加到開頭。即新的新節點將成爲鏈接列表的頭部

temp->next = *list;//Store pointer to earlier head as the next node 
*list = temp; // Make pointer new node as the head node 

在您的代碼中,雙指針作爲參數傳遞到函數中。 即,如果A是您的指針頭節點,則包含A的地址B將作爲參數傳遞到您的函數中。