2019-05-10 10:01:15 +00:00
|
|
|
package linkedlist
|
|
|
|
|
2019-05-17 11:54:55 +00:00
|
|
|
import "fmt"
|
|
|
|
|
2019-05-10 10:01:15 +00:00
|
|
|
type Node struct {
|
2019-05-17 11:54:55 +00:00
|
|
|
prev *Node
|
2019-05-10 10:01:15 +00:00
|
|
|
next *Node
|
|
|
|
value interface{}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (node *Node) Value() interface{} {
|
|
|
|
return node.value
|
|
|
|
}
|
|
|
|
|
|
|
|
type LinkedList struct {
|
|
|
|
head *Node
|
2019-05-17 11:54:55 +00:00
|
|
|
tail *Node
|
2019-05-10 10:01:15 +00:00
|
|
|
size uint
|
|
|
|
}
|
|
|
|
|
2019-05-17 11:54:55 +00:00
|
|
|
// var nodePool *sync.Pool = &sync.Pool{
|
|
|
|
// New: func() interface{} {
|
|
|
|
// return &Node{}
|
|
|
|
// },
|
|
|
|
// }
|
|
|
|
|
2019-05-10 10:01:15 +00:00
|
|
|
func New() *LinkedList {
|
2019-05-17 11:54:55 +00:00
|
|
|
l := &LinkedList{}
|
|
|
|
l.head = &Node{}
|
|
|
|
l.head.prev = nil
|
|
|
|
|
|
|
|
l.tail = &Node{}
|
|
|
|
l.tail.next = nil
|
|
|
|
|
|
|
|
l.head.next = l.tail
|
|
|
|
l.tail.prev = l.head
|
|
|
|
return l
|
2019-05-10 10:01:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (l *LinkedList) Size() uint {
|
|
|
|
return l.size
|
|
|
|
}
|
|
|
|
|
2019-05-17 11:54:55 +00:00
|
|
|
func (l *LinkedList) PushFront(values ...interface{}) {
|
|
|
|
|
|
|
|
var node *Node
|
|
|
|
l.size += uint(len(values))
|
|
|
|
for _, v := range values {
|
|
|
|
node = &Node{}
|
|
|
|
node.value = v
|
|
|
|
|
|
|
|
hnext := l.head.next
|
|
|
|
hnext.prev = node
|
|
|
|
|
|
|
|
node.next = hnext
|
|
|
|
node.prev = l.head
|
|
|
|
l.head.next = node
|
2019-05-10 10:01:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-17 11:54:55 +00:00
|
|
|
func (l *LinkedList) PushBack(values ...interface{}) {
|
|
|
|
|
|
|
|
var node *Node
|
|
|
|
l.size += uint(len(values))
|
|
|
|
for _, v := range values {
|
|
|
|
node = &Node{}
|
|
|
|
node.value = v
|
|
|
|
|
|
|
|
tprev := l.tail.prev
|
|
|
|
tprev.next = node
|
2019-05-10 10:01:15 +00:00
|
|
|
|
2019-05-17 11:54:55 +00:00
|
|
|
node.prev = tprev
|
|
|
|
node.next = l.tail
|
|
|
|
l.tail.prev = node
|
|
|
|
}
|
2019-05-10 10:01:15 +00:00
|
|
|
}
|
|
|
|
|
2019-05-17 11:54:55 +00:00
|
|
|
func (l *LinkedList) PopFront() (result interface{}, found bool) {
|
|
|
|
if l.size != 0 {
|
|
|
|
l.size--
|
|
|
|
|
|
|
|
temp := l.head.next
|
|
|
|
hnext := temp.next
|
|
|
|
hnext.prev = l.head
|
|
|
|
l.head.next = hnext
|
|
|
|
|
|
|
|
result = temp.value
|
|
|
|
found = true
|
|
|
|
return
|
2019-05-10 10:01:15 +00:00
|
|
|
}
|
|
|
|
return nil, false
|
|
|
|
}
|
|
|
|
|
2019-05-17 11:54:55 +00:00
|
|
|
func (l *LinkedList) PopBack() (result interface{}, found bool) {
|
|
|
|
if l.size != 0 {
|
|
|
|
l.size--
|
|
|
|
|
|
|
|
temp := l.tail.prev
|
|
|
|
tprev := temp.prev
|
|
|
|
tprev.next = l.tail
|
|
|
|
l.tail.prev = tprev
|
|
|
|
|
|
|
|
result = temp.value
|
|
|
|
found = true
|
|
|
|
return
|
2019-05-10 10:01:15 +00:00
|
|
|
}
|
2019-05-17 11:54:55 +00:00
|
|
|
return nil, false
|
|
|
|
}
|
2019-05-10 10:01:15 +00:00
|
|
|
|
2019-05-17 11:54:55 +00:00
|
|
|
func (l *LinkedList) Front() (result interface{}, found bool) {
|
|
|
|
if l.size != 0 {
|
|
|
|
return l.head.next.value, true
|
|
|
|
}
|
|
|
|
return nil, false
|
2019-05-10 10:01:15 +00:00
|
|
|
}
|
|
|
|
|
2019-05-17 11:54:55 +00:00
|
|
|
func (l *LinkedList) Back() (result interface{}, found bool) {
|
|
|
|
if l.size != 0 {
|
|
|
|
return l.tail.prev.value, true
|
2019-05-10 10:01:15 +00:00
|
|
|
}
|
2019-05-17 11:54:55 +00:00
|
|
|
return nil, false
|
|
|
|
}
|
2019-05-10 10:01:15 +00:00
|
|
|
|
2019-05-17 11:54:55 +00:00
|
|
|
func (l *LinkedList) Insert(idx uint, values ...interface{}) {
|
|
|
|
if idx > l.size {
|
2019-05-10 10:01:15 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2019-05-17 11:54:55 +00:00
|
|
|
if idx > l.size/2 {
|
|
|
|
idx = l.size - idx
|
|
|
|
// 尾部
|
|
|
|
for cur := l.tail.prev; cur != nil; cur = cur.prev {
|
|
|
|
|
|
|
|
if idx == 0 {
|
|
|
|
|
|
|
|
var start *Node
|
|
|
|
var end *Node
|
|
|
|
|
|
|
|
start = &Node{value: values[0]}
|
|
|
|
end = start
|
|
|
|
|
|
|
|
for _, value := range values[1:] {
|
|
|
|
node := &Node{value: value}
|
|
|
|
end.next = node
|
|
|
|
node.prev = end
|
|
|
|
end = node
|
|
|
|
}
|
|
|
|
|
|
|
|
cnext := cur.next
|
|
|
|
|
|
|
|
cur.next = start
|
|
|
|
start.prev = cur
|
|
|
|
|
|
|
|
end.next = cnext
|
|
|
|
cnext.prev = end
|
|
|
|
|
|
|
|
break
|
|
|
|
}
|
|
|
|
|
|
|
|
idx--
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
// 头部
|
|
|
|
for cur := l.head.next; cur != nil; cur = cur.next {
|
|
|
|
if idx == 0 {
|
|
|
|
|
|
|
|
var start *Node
|
|
|
|
var end *Node
|
|
|
|
|
|
|
|
start = &Node{value: values[0]}
|
|
|
|
end = start
|
|
|
|
|
|
|
|
for _, value := range values[1:] {
|
|
|
|
node := &Node{value: value}
|
|
|
|
end.next = node
|
|
|
|
node.prev = end
|
|
|
|
end = node
|
|
|
|
}
|
|
|
|
|
|
|
|
cprev := cur.prev
|
|
|
|
|
|
|
|
cprev.next = start
|
|
|
|
start.prev = cprev
|
|
|
|
|
|
|
|
end.next = cur
|
|
|
|
cur.prev = end
|
|
|
|
|
|
|
|
break
|
|
|
|
}
|
|
|
|
|
|
|
|
idx--
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
l.size += uint(len(values))
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l *LinkedList) Remove(idx uint) {
|
|
|
|
if idx >= l.size {
|
|
|
|
panic(fmt.Sprintf("out of list range, size is %d, idx is %d", l.size, idx))
|
|
|
|
}
|
|
|
|
if l.head != nil {
|
|
|
|
if idx == 0 {
|
2019-05-10 10:01:15 +00:00
|
|
|
l.size--
|
2019-05-17 11:54:55 +00:00
|
|
|
temp := l.head
|
|
|
|
l.head = l.head.next
|
|
|
|
nodePool.Put(temp)
|
2019-05-10 10:01:15 +00:00
|
|
|
return
|
|
|
|
}
|
2019-05-17 11:54:55 +00:00
|
|
|
|
|
|
|
for cur := l.head; cur.next != nil; cur = cur.next {
|
|
|
|
if idx == 1 {
|
|
|
|
l.size--
|
|
|
|
result := cur.next
|
|
|
|
cur.next = result.next
|
|
|
|
result.next = nil
|
|
|
|
nodePool.Put(result)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
idx--
|
|
|
|
}
|
2019-05-10 10:01:15 +00:00
|
|
|
}
|
|
|
|
|
2019-05-17 11:54:55 +00:00
|
|
|
return
|
2019-05-10 10:01:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (l *LinkedList) Values() (result []interface{}) {
|
2019-05-17 11:54:55 +00:00
|
|
|
l.Traversal(func(value interface{}) bool {
|
|
|
|
result = append(result, value)
|
2019-05-10 10:01:15 +00:00
|
|
|
return true
|
|
|
|
})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2019-05-17 11:54:55 +00:00
|
|
|
func (l *LinkedList) Traversal(every func(interface{}) bool) {
|
|
|
|
for cur := l.head.next; cur != l.tail; cur = cur.next {
|
|
|
|
if !every(cur.value) {
|
2019-05-10 10:01:15 +00:00
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|