2015-05-08 46 views
0

試圖用簡單的addToLast函數實現LinkedList(它將新節點添加到鏈表的末尾)而不是使用內置列表) 下面是代碼(用於調試的已刪除的打印語句):鏈表實現指針故障

package main 

import "fmt" 

var first *Link 
var last Link 

func main() { 
    AddToLast(10) 
    AddToLast(20) 
} 

func AddToLast(d int) { 
    if first == nil { 
     last = Link{d, new(Link)} 
     first = &last 
    } else { 
     last.next = &Link{d, new(Link)} 
     last = *last.next 
    } 
} 

type Link struct { 
    data int 
    next *Link 
} 

我上面的代碼的理解:

內AddToLast功能 - 檢查,如果「第一」是零,即它不具有任何元素後,「最後」的 10創建作爲數據和新的空鏈接作爲下一個。現在'第一'被賦予相同的值 作爲'最後',但使用內存地址(作爲參考 - 我不知道如果我的理解是不正確的)

現在,當我們嘗試插入20 )'AddToLast'中的else部分被執行。 'last.next'被分配一個值爲20的鏈接,它的下一個爲零。現在'last'被移動到'last.next', 以確保'last'總是指向最後一個節點。但是由於我將'last'移動到'last.next','last'('s)的內存地址變化很明顯,並且這也導致首先指向新的最後一個,即值爲20.

爲了避免這種情況,我嘗試將「first」聲明爲Link而不是* Link。 但是,這樣做並不會使first.next指向新節點,也就是20.我很困惑,因爲我不認爲正確的地方。

+0

你自己說,你正在使'第一個'指向與'last'相同的結構。因此,只要你改變'last',它就會改變'first'。不要這樣做。 – JimB

+0

正確,但是如果我聲明'first'爲'Link'而不是當前聲明爲'* Link'。後來,當我分配'first' ='last'時,這意味着它是一個副本而不是引用。但是這樣做會導致我提到的問題,即 - 當添加20時,'first.next'不指向20,它指向{0,}。 – srock

+0

是的,不要改變'last',你不會有這個問題。我會把它放在一個答案 – JimB

回答

2

不要改變last中的元素值,因爲該元素已經創建。新建一個last,並將之前的next指針設置爲指向它。這是一個修改後的版本:http://play.golang.org/p/-X5RayC0gU

var first *Link 
var last *Link 

func AddToLast(d int) { 
    next := &Link{d, nil} 
    if first == nil { 
     first = next 
    } else { 
     last.next = next 
    } 
    last = next 
} 

type Link struct { 
    data int 
    next *Link 
} 
+0

謝謝@JimB。所以基本上當你做'last = next'的時候,你指的是'last'到'next'的地址。那是對的嗎?我認爲使用Java使我的指針更生鏽:)。再次感謝你的幫助。真的很高興看到像你這樣的人幫助golang社區! – srock

+0

@srock:正確。 'last'和'next'是指針,所以'last = next'將'next'的地址賦給'last'。 – JimB