fix linkedlist
This commit is contained in:
parent
0230950382
commit
8d5b098286
|
@ -121,6 +121,34 @@ func (l *LinkedList) Back() (result interface{}, found bool) {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
// 尾部
|
||||||
|
for cur := l.tail.prev; cur != nil; cur = cur.prev {
|
||||||
|
if idx == 0 {
|
||||||
|
return cur.value, true
|
||||||
|
}
|
||||||
|
idx--
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// 头部
|
||||||
|
for cur := l.head.next; cur != nil; cur = cur.next {
|
||||||
|
if idx == 0 {
|
||||||
|
return cur.value, true
|
||||||
|
}
|
||||||
|
idx--
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
func (l *LinkedList) Insert(idx uint, values ...interface{}) {
|
func (l *LinkedList) Insert(idx uint, values ...interface{}) {
|
||||||
if idx > l.size {
|
if idx > l.size {
|
||||||
return
|
return
|
||||||
|
@ -196,33 +224,81 @@ func (l *LinkedList) Insert(idx uint, values ...interface{}) {
|
||||||
l.size += uint(len(values))
|
l.size += uint(len(values))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *LinkedList) Remove(idx uint) {
|
func (l *LinkedList) InsertIf(every func(idx uint, cur *Node) int, values ...interface{}) {
|
||||||
|
|
||||||
|
idx := uint(0)
|
||||||
|
// 头部
|
||||||
|
for cur := l.head.next; cur != nil; cur = cur.next {
|
||||||
|
|
||||||
|
if every(idx, cur) != 0 { // 1 为前 -1 为后
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
l.size += uint(len(values))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *LinkedList) Remove(idx uint) (interface{}, bool) {
|
||||||
if idx >= l.size {
|
if idx >= l.size {
|
||||||
panic(fmt.Sprintf("out of list range, size is %d, idx is %d", l.size, idx))
|
panic(fmt.Sprintf("out of list range, size is %d, idx is %d", l.size, idx))
|
||||||
}
|
}
|
||||||
if l.head != nil {
|
|
||||||
if idx == 0 {
|
if idx > l.size/2 {
|
||||||
l.size--
|
idx = l.size - 1 - idx
|
||||||
temp := l.head
|
// 尾部
|
||||||
l.head = l.head.next
|
for cur := l.tail.prev; cur != nil; cur = cur.prev {
|
||||||
nodePool.Put(temp)
|
if idx == 0 {
|
||||||
return
|
curPrev := cur.prev
|
||||||
|
curNext := cur.next
|
||||||
|
curPrev.next = curNext
|
||||||
|
curNext.prev = curPrev
|
||||||
|
cur.prev = nil
|
||||||
|
cur.next = nil
|
||||||
|
return cur.value, true
|
||||||
|
}
|
||||||
|
idx--
|
||||||
}
|
}
|
||||||
|
|
||||||
for cur := l.head; cur.next != nil; cur = cur.next {
|
} else {
|
||||||
if idx == 1 {
|
// 头部
|
||||||
l.size--
|
for cur := l.head.next; cur != nil; cur = cur.next {
|
||||||
result := cur.next
|
if idx == 0 {
|
||||||
cur.next = result.next
|
curPrev := cur.prev
|
||||||
result.next = nil
|
curNext := cur.next
|
||||||
nodePool.Put(result)
|
curPrev.next = curNext
|
||||||
return
|
curNext.prev = curPrev
|
||||||
|
cur.prev = nil
|
||||||
|
cur.next = nil
|
||||||
|
return cur.value, true
|
||||||
|
|
||||||
}
|
}
|
||||||
idx--
|
idx--
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
panic(fmt.Sprintf("unknown error"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *LinkedList) Values() (result []interface{}) {
|
func (l *LinkedList) Values() (result []interface{}) {
|
||||||
|
|
|
@ -45,7 +45,7 @@ func TestPushBack(t *testing.T) {
|
||||||
|
|
||||||
func TestPopFront(t *testing.T) {
|
func TestPopFront(t *testing.T) {
|
||||||
l := New()
|
l := New()
|
||||||
// "[0 1 2 3 4]"
|
// "[4 3 2 1 0]"
|
||||||
for i := 0; i < 5; i++ {
|
for i := 0; i < 5; i++ {
|
||||||
l.PushFront(i)
|
l.PushFront(i)
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,7 @@ func TestPopFront(t *testing.T) {
|
||||||
|
|
||||||
func TestPopBack(t *testing.T) {
|
func TestPopBack(t *testing.T) {
|
||||||
l := New()
|
l := New()
|
||||||
// "[0 1 2 3 4]"
|
// "[4 3 2 1 0]"
|
||||||
for i := 0; i < 5; i++ {
|
for i := 0; i < 5; i++ {
|
||||||
l.PushFront(i)
|
l.PushFront(i)
|
||||||
}
|
}
|
||||||
|
@ -127,6 +127,58 @@ func TestInsert(t *testing.T) {
|
||||||
if result1 != "[4 99 3 2 1 0 0 1 2 3 4]" {
|
if result1 != "[4 99 3 2 1 0 0 1 2 3 4]" {
|
||||||
t.Error("[4 3 2 1 0 0 1 2 3 4] insert with index 1, should be [4 99 3 2 1 0 0 1 2 3 4]\n but result is", result1)
|
t.Error("[4 3 2 1 0 0 1 2 3 4] insert with index 1, should be [4 99 3 2 1 0 0 1 2 3 4]\n but result is", result1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
l1.Insert(9, 99)
|
||||||
|
result1 = spew.Sprint(l1.Values())
|
||||||
|
if result1 != "[4 99 3 2 1 0 0 1 2 99 3 4]" {
|
||||||
|
t.Error("[4 99 3 2 1 0 0 1 2 3 4] insert with index 9, should be [4 99 3 2 1 0 0 1 2 99 3 4]\n but result is", result1)
|
||||||
|
}
|
||||||
|
|
||||||
|
l1.Insert(12, 99)
|
||||||
|
result1 = spew.Sprint(l1.Values())
|
||||||
|
if result1 != "[4 99 3 2 1 0 0 1 2 99 3 4 99]" {
|
||||||
|
t.Error("[4 99 3 2 1 0 0 1 2 99 3 4] insert with index 12, should be [4 99 3 2 1 0 0 1 2 99 3 4 99]\n but result is", result1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIndex(t *testing.T) {
|
||||||
|
l := New()
|
||||||
|
// "[4 3 2 1 0]"
|
||||||
|
for i := 0; i < 5; i++ {
|
||||||
|
l.PushFront(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
if v, ok := l.Index(4); ok {
|
||||||
|
if v != 0 {
|
||||||
|
t.Error("[4 3 2 1 0] Index 4 value is 0, but v is ", v)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
t.Error("not ok is error")
|
||||||
|
}
|
||||||
|
|
||||||
|
if v, ok := l.Index(1); ok {
|
||||||
|
if v != 3 {
|
||||||
|
t.Error("[4 3 2 1 0] Index 1 value is 3, but v is ", v)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
t.Error("not ok is error")
|
||||||
|
}
|
||||||
|
|
||||||
|
if v, ok := l.Index(0); ok {
|
||||||
|
if v != 4 {
|
||||||
|
t.Error("[4 3 2 1 0] Index 1 value is 4, but v is ", v)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
t.Error("not ok is error")
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := l.Index(5); ok {
|
||||||
|
t.Error("[4 3 2 1 0] Index 5, out of range,ok = true is error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRemove(t *testing.T) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkPushBack(b *testing.B) {
|
func BenchmarkPushBack(b *testing.B) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user