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
|
|
|
}
|
|
|
|
|
2019-05-22 09:52:50 +00:00
|
|
|
func (l *LinkedList) Clear() {
|
|
|
|
l.head.next = nil
|
|
|
|
l.tail.prev = nil
|
|
|
|
l.size = 0
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l *LinkedList) Empty() bool {
|
|
|
|
return l.size == 0
|
|
|
|
}
|
|
|
|
|
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-21 06:28:08 +00:00
|
|
|
func (l *LinkedList) Find(every func(idx uint, value interface{}) bool) (interface{}, bool) {
|
|
|
|
|
|
|
|
idx := uint(0)
|
|
|
|
// 头部
|
|
|
|
for cur := l.head.next; cur != l.tail; cur = cur.next {
|
|
|
|
if every(idx, cur.value) {
|
|
|
|
return cur.value, true
|
|
|
|
}
|
|
|
|
idx++
|
|
|
|
}
|
|
|
|
return nil, false
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l *LinkedList) FindMany(every func(idx uint, value interface{}) int) (result []interface{}, isfound bool) {
|
|
|
|
// the default of isfould is false
|
|
|
|
idx := uint(0)
|
|
|
|
// 头部
|
|
|
|
for cur := l.head.next; cur != l.tail; cur = cur.next {
|
|
|
|
j := every(idx, cur.value)
|
|
|
|
switch {
|
|
|
|
case j > 0:
|
|
|
|
result = append(result, cur.value)
|
|
|
|
isfound = true
|
|
|
|
case j < 0:
|
|
|
|
return result, isfound
|
|
|
|
}
|
|
|
|
idx++
|
|
|
|
}
|
|
|
|
return result, isfound
|
|
|
|
}
|
|
|
|
|
2019-05-19 18:14:46 +00:00
|
|
|
func (l *LinkedList) Index(idx uint) (interface{}, bool) {
|
|
|
|
if idx >= l.size {
|
|
|
|
return nil, false
|
|
|
|
}
|
|
|
|
|
|
|
|
if idx > l.size/2 {
|
|
|
|
idx = l.size - 1 - idx
|
|
|
|
// 尾部
|
2019-05-21 06:28:08 +00:00
|
|
|
for cur := l.tail.prev; cur != l.head; cur = cur.prev {
|
2019-05-19 18:14:46 +00:00
|
|
|
if idx == 0 {
|
|
|
|
return cur.value, true
|
|
|
|
}
|
|
|
|
idx--
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
// 头部
|
2019-05-21 06:28:08 +00:00
|
|
|
for cur := l.head.next; cur != l.tail; cur = cur.next {
|
2019-05-19 18:14:46 +00:00
|
|
|
if idx == 0 {
|
|
|
|
return cur.value, true
|
|
|
|
}
|
|
|
|
idx--
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil, false
|
|
|
|
}
|
|
|
|
|
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))
|
|
|
|
}
|
|
|
|
|
2019-05-21 02:54:30 +00:00
|
|
|
func (l *LinkedList) InsertIf(every func(idx uint, value interface{}) int, values ...interface{}) {
|
2019-05-19 18:14:46 +00:00
|
|
|
|
|
|
|
idx := uint(0)
|
|
|
|
// 头部
|
|
|
|
for cur := l.head.next; cur != nil; cur = cur.next {
|
2019-05-21 02:54:30 +00:00
|
|
|
isInsert := every(idx, cur.value)
|
|
|
|
if isInsert != 0 { // 1 为前 -1 为后 insert here(-1) ->cur-> insert here(1)
|
2019-05-19 18:14:46 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2019-05-21 02:54:30 +00:00
|
|
|
if isInsert < 0 {
|
|
|
|
cprev := cur.prev
|
|
|
|
cprev.next = start
|
|
|
|
start.prev = cprev
|
|
|
|
end.next = cur
|
|
|
|
cur.prev = end
|
|
|
|
} else {
|
|
|
|
cnext := cur.next
|
|
|
|
cnext.prev = end
|
|
|
|
start.prev = cur
|
|
|
|
cur.next = start
|
|
|
|
end.next = cnext
|
|
|
|
}
|
2019-05-19 18:14:46 +00:00
|
|
|
|
2019-05-21 06:28:08 +00:00
|
|
|
l.size += uint(len(values))
|
2019-05-21 02:54:30 +00:00
|
|
|
break
|
2019-05-19 18:14:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-21 02:54:30 +00:00
|
|
|
func remove(cur *Node) {
|
|
|
|
curPrev := cur.prev
|
|
|
|
curNext := cur.next
|
|
|
|
curPrev.next = curNext
|
|
|
|
curNext.prev = curPrev
|
|
|
|
cur.prev = nil
|
|
|
|
cur.next = nil
|
|
|
|
}
|
|
|
|
|
2019-05-19 18:14:46 +00:00
|
|
|
func (l *LinkedList) Remove(idx uint) (interface{}, bool) {
|
2019-05-17 11:54:55 +00:00
|
|
|
if idx >= l.size {
|
|
|
|
panic(fmt.Sprintf("out of list range, size is %d, idx is %d", l.size, idx))
|
|
|
|
}
|
2019-05-19 18:14:46 +00:00
|
|
|
|
2019-05-20 11:12:38 +00:00
|
|
|
l.size--
|
2019-05-19 18:14:46 +00:00
|
|
|
if idx > l.size/2 {
|
2019-05-21 02:54:30 +00:00
|
|
|
idx = l.size - idx // l.size - 1 - idx, 先减size
|
2019-05-19 18:14:46 +00:00
|
|
|
// 尾部
|
2019-05-21 06:28:08 +00:00
|
|
|
for cur := l.tail.prev; cur != l.head; cur = cur.prev {
|
2019-05-19 18:14:46 +00:00
|
|
|
if idx == 0 {
|
2019-05-21 02:54:30 +00:00
|
|
|
remove(cur)
|
2019-05-19 18:14:46 +00:00
|
|
|
return cur.value, true
|
|
|
|
}
|
|
|
|
idx--
|
2019-05-10 10:01:15 +00:00
|
|
|
}
|
2019-05-17 11:54:55 +00:00
|
|
|
|
2019-05-19 18:14:46 +00:00
|
|
|
} else {
|
|
|
|
// 头部
|
2019-05-21 06:28:08 +00:00
|
|
|
for cur := l.head.next; cur != l.tail; cur = cur.next {
|
2019-05-19 18:14:46 +00:00
|
|
|
if idx == 0 {
|
2019-05-21 02:54:30 +00:00
|
|
|
remove(cur)
|
2019-05-19 18:14:46 +00:00
|
|
|
return cur.value, true
|
|
|
|
|
2019-05-17 11:54:55 +00:00
|
|
|
}
|
|
|
|
idx--
|
|
|
|
}
|
2019-05-10 10:01:15 +00:00
|
|
|
}
|
|
|
|
|
2019-05-19 18:14:46 +00:00
|
|
|
panic(fmt.Sprintf("unknown error"))
|
2019-05-10 10:01:15 +00:00
|
|
|
}
|
|
|
|
|
2019-05-21 06:28:08 +00:00
|
|
|
func (l *LinkedList) RemoveIf(every func(idx uint, value interface{}) int) (result []interface{}, isRemoved bool) {
|
2019-05-21 02:54:30 +00:00
|
|
|
// 头部
|
2019-05-21 06:28:08 +00:00
|
|
|
idx := uint(0)
|
|
|
|
for cur := l.head.next; cur != l.tail; idx++ {
|
|
|
|
j := every(idx, cur.value)
|
|
|
|
switch {
|
|
|
|
case j > 0:
|
|
|
|
result = append(result, cur.value)
|
|
|
|
isRemoved = true
|
|
|
|
temp := cur.next
|
2019-05-21 02:54:30 +00:00
|
|
|
remove(cur)
|
2019-05-21 06:28:08 +00:00
|
|
|
cur = temp
|
|
|
|
l.size--
|
|
|
|
continue
|
|
|
|
case j < 0:
|
|
|
|
return
|
2019-05-21 02:54:30 +00:00
|
|
|
}
|
|
|
|
|
2019-05-21 06:28:08 +00:00
|
|
|
cur = cur.next
|
|
|
|
}
|
|
|
|
return
|
2019-05-21 02:54:30 +00:00
|
|
|
}
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|