单链表定义
此处将 Node 和 List 分开定义,方便理解,官方的方法是把两个结构合并,
戳:https://golang.org/src/container/list/list.go?s=2063:2093#L14
type Node struct {
value interface{}
next *Node
}
type List struct {
len int
head *Node
tail *Node
}
接口列表
非必要可以省略此步骤,此处使用 Interface 只是为了方便阅读和展示。
type SingleLinkedList interface {
Init()
Len() int
PushFront(v interface{})
PushBack(v interface{})
Insert(v interface{}, index int) error
RemoveFront() interface{}
RemoveBack() interface{}
Remove(index int) interface{}
GetHead() *Node
Get(index int) interface{}
}
初始化
初始化操作,需要手动初始化,也可以实现在首次插入时进行初始化操作。
func (l *List) Init() {
l.len = 0
l.head = nil
l.tail = nil
}
链表长度
func (l *List) Len() int {
return l.len
}
添加操作
新节点三种插入方式,分别是 头部插入、末尾插入、指定位置插入。
// 从链表头部插入一个新节点
func (l *List) PushFront(v interface{}) {
node := &Node{
value: v,
next: nil,
}
if l.len == 0 {
l.tail = node
} else {
node.next = l.head
}
l.head = node
l.len++
}
// 从链表尾部插入一个新节点
func (l *List) PushBack(v interface{}) {
node := &Node{
value: v,
next: nil,
}
if l.len == 0 {
l.head = node
} else {
l.tail.next = node
}
l.tail = node
l.len++
}
// 指定位置,插入新节点
func (l *List) Insert(v interface{}, index int) error {
if index >= l.len {
return errors.New("index error")
}
if index == 0 {
l.PushFront(v)
return nil
}
node := &Node{
value: v,
next: nil,
}
prev := l.head
for i := 1; i < l.len; i++ {
if i == index {
node.next = prev.next
prev.next = node
l.len++
return nil
}
prev = prev.next
}
return errors.New("insert error")
}
移除操作
三种移除操作,移除头部、移除尾部、指定位置移除。
// 移除头部节点
func (l *List) RemoveFront() interface{} {
if l.len == 0 {
return nil
}
node := l.head
l.head = l.head.next
l.len--
return node.value
}
// 移除尾部节点
func (l *List) RemoveBack() interface{} {
if l.len == 0 {
return nil
}
node := l.head
for i := 1; i < l.len-1; i++ {
node = node.next
}
tmp := node.next
node.next = nil
l.tail = node
l.len--
return tmp.value
}
// 指定位置移除节点
func (l *List) Remove(index int) interface{} {
if l.len == 0 {
return nil
}
if index == 0 {
return l.RemoveFront()
} else if index == l.len-1 {
return l.RemoveBack()
}
node := l.head
for i := 1; i < index; i++ {
node = node.next
}
tmp := node.next
node.next = node.next.next
l.len--
return tmp.value
}
获取节点
// 获取头部节点
func (l *List) GetHead() *Node {
return l.head
}
// 获取指定位置的节点值
func (l *List) Get(index int) interface{} {
if index >= l.len {
return nil
}
node := l.head
for i := 0; i < l.len; i++ {
if i == index {
return node.value
}
node = node.next
}
return nil
}
测试
完整代码见:
github.com/zzir/algo/b…
测试用例:
func main() {
var sl SingleLinkedList = &List{}
sl.Init()
sl.PushFront(6)
sl.PushFront(7)
sl.PushFront(8)
sl.PushBack(1)
sl.PushBack(2)
sl.PushBack(3)
fmt.Println("r", sl.RemoveFront())
_ = sl.Insert(9, 0)
_ = sl.Insert(8, 5)
fmt.Println("r", sl.RemoveBack())
fmt.Println("r", sl.RemoveBack())
fmt.Println("rm", sl.Remove(1))
fmt.Println("rm", sl.Remove(2))
fmt.Println("len", sl.Len())
node := sl.GetHead()
for {
fmt.Println(">>>", node.value)
if node.next == nil {
break
}
node = node.next
}
fmt.Println(sl.Get(1))
}