linkedList.go
中的第一个代码段如下:
在这部分代码中,我们定义了用作链表节点的 Node
结构类型和保存链表第一个元素的全局变量 root
,在代码的其他任何地方我们都能访问这个变量。
linkedList.go
的第二部分是如下的 Go 代码:
func addNode(t *Node, v int) int {
if root == nil {
t = &Node{v, nil}
root = t
return 0
}
if v == t.Value {
fmt.Println("Node already exists:", v)
return -1
}
if t.Next == nil {
t.Next = &Node{v, nil}
return -2
}
return addNode(t.Next, v)
}
因此,addNode()
函数的功能就是向链表中添加新的节点。这个实现中使用 if
语句检查了三种不同的情况。第一种情况,检查要处理的链表是否为空。第二种情况,检查将要插入的值是否已经存在。第三种情况,检查是否已经到达了链表的末端,这时,使用 将含有给定值的新节点加入链表的末端。如果所有的情况都不满足,则使用 return addNode(t.Next, v)
对链表中下一个节点调用 addNode()
,重复上面的过程。
linkedList.go
程序的第三个代码片段包含了 traverse()
函数的实现:
linkedList.go
的第四部分如下:
if root == nil {
t = &Node{v, nil}
root = t
return false
}
if v == t.Value {
return true
}
if t.Next == nil {
return false
}
return lookupNode(t.Next, v)
}
func size(t *Node) int {
if t == nil {
return 0
}
i := 0
for t != nil {
i++
t = t.Next
}
return i
}
lookupNode()
函数实现背后的逻辑很容易理解:依次访问单向链表中所有的元素来查找你想要的值。如果你从头到尾都没找到想要的值,那就说明链表中没有这个值。
linkedList.go
的最后一部分包含 main()
函数的实现:
执行 linkedList.go
将生成如下的输出:
$ go run linkedList.go
&{0 <nil>}
-> Empty list!
1 -> -1 ->
Node already exists: 5
Node already exists: 5
1 -> -1 -> 10 -> 5 -> 45 ->
1 -> -1 -> 10 -> 5 -> 45 -> 100 ->
Node exists!