linkedList.go 中的第一个代码段如下:

    在这部分代码中,我们定义了用作链表节点的 Node 结构类型和保存链表第一个元素的全局变量 root,在代码的其他任何地方我们都能访问这个变量。

    linkedList.go 的第二部分是如下的 Go 代码:

    1. func addNode(t *Node, v int) int {
    2. if root == nil {
    3. t = &Node{v, nil}
    4. root = t
    5. return 0
    6. }
    7. if v == t.Value {
    8. fmt.Println("Node already exists:", v)
    9. return -1
    10. }
    11. if t.Next == nil {
    12. t.Next = &Node{v, nil}
    13. return -2
    14. }
    15. return addNode(t.Next, v)
    16. }

    因此,addNode() 函数的功能就是向链表中添加新的节点。这个实现中使用 if 语句检查了三种不同的情况。第一种情况,检查要处理的链表是否为空。第二种情况,检查将要插入的值是否已经存在。第三种情况,检查是否已经到达了链表的末端,这时,使用 将含有给定值的新节点加入链表的末端。如果所有的情况都不满足,则使用 return addNode(t.Next, v) 对链表中下一个节点调用 addNode(),重复上面的过程。

    linkedList.go 程序的第三个代码片段包含了 traverse() 函数的实现:

    linkedList.go 的第四部分如下:

    1. if root == nil {
    2. t = &Node{v, nil}
    3. root = t
    4. return false
    5. }
    6. if v == t.Value {
    7. return true
    8. }
    9. if t.Next == nil {
    10. return false
    11. }
    12. return lookupNode(t.Next, v)
    13. }
    14. func size(t *Node) int {
    15. if t == nil {
    16. return 0
    17. }
    18. i := 0
    19. for t != nil {
    20. i++
    21. t = t.Next
    22. }
    23. return i
    24. }

    lookupNode() 函数实现背后的逻辑很容易理解:依次访问单向链表中所有的元素来查找你想要的值。如果你从头到尾都没找到想要的值,那就说明链表中没有这个值。

    linkedList.go 的最后一部分包含 main() 函数的实现:

    执行 linkedList.go 将生成如下的输出:

    1. $ go run linkedList.go
    2. &{0 <nil>}
    3. -> Empty list!
    4. 1 -> -1 ->
    5. Node already exists: 5
    6. Node already exists: 5
    7. 1 -> -1 -> 10 -> 5 -> 45 ->
    8. 1 -> -1 -> 10 -> 5 -> 45 -> 100 ->
    9. Node exists!