链表就如环环相扣的锁链搬将各个节点的数据连接在一起
每个数据节点除了存储节点值以外,还存储了下一个节点的地址指针,从而可以通过本节点寻找下一个节点,哪怕下一个节点的实际存储位置与本节点不连续,也不太会影响寻址效率。故一般我们用链表来组织碎片化的空间。
链表的插入和删除并不会影响到其他大部分的节点,只涉及到目标节点前后的节点操作,所以效率极高为O(1)
缺点就是查询效率较低,要在链表中查询某个节点必须按顺序遍历链表来查询,时间复杂度为O(n)
下面是单链表的示意图
下面上单链表的实现代码
package list
type node struct {
v int
p *node
}
var rootNode = new(node)
// addNode 新增节点
func addNode(v int) {
if rootNode.v == 0 {
rootNode.v = v
return
}
var newNode = &node{
v: v,
p: nil,
}
rootNode.findLastNode().p = newNode
}
// findLastNode 获取链表中最后一个节点
func (n *node) findLastNode() *node {
if n.p == nil {
return n
}
return n.p.findLastNode()
}
// traverse 遍历打印
func (n *node) traverse() {
println(n.v)
if n.p == nil {
return
}
n.p.traverse()
}
// find 查找某个value所在的node
func (n *node) find(v int) *node {
if n.v == v {
return n
}
if n.p == nil {
return nil
}
return n.p.find(v)
}
// delete 删除某个节点
func (n *node) delete(v int) {
if n.v == v {
if n.p != nil {
n.v = n.p.v
n.p = n.p.p
return
}
n = nil
return
}
n.p.findToDelete(v, n)
}
// findToDelete 遍历删除
func(n *node) findToDelete(v int, lastn *node) {
if n.v == v {
lastn.p = n.p
return
}
if n.p == nil {
return
}
n.p.findToDelete(v, n)
}
package list
import "testing"
func Test_AddNode(t *testing.T) {
addNode(1)
addNode(2)
addNode(3)
addNode(4)
addNode(5)
addNode(6)
addNode(7)
addNode(8)
addNode(9)
rootNode.delete(7)
rootNode.delete(3)
rootNode.delete(1)
rootNode.traverse()
t.Log(rootNode.findLastNode().v)
t.Log(rootNode.find(7).v)
}