这!就是单向链表【go实现

545 阅读1分钟

链表就如环环相扣的锁链搬将各个节点的数据连接在一起

每个数据节点除了存储节点值以外,还存储了下一个节点的地址指针,从而可以通过本节点寻找下一个节点,哪怕下一个节点的实际存储位置与本节点不连续,也不太会影响寻址效率。故一般我们用链表来组织碎片化的空间。

链表的插入和删除并不会影响到其他大部分的节点,只涉及到目标节点前后的节点操作,所以效率极高为O(1)

缺点就是查询效率较低,要在链表中查询某个节点必须按顺序遍历链表来查询,时间复杂度为O(n) ​

下面是单链表的示意图 链表.png

下面上单链表的实现代码

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)
}