From 8d5b0982869c382ce3d2a7ff748a437812fb967d Mon Sep 17 00:00:00 2001 From: eson <474420502@qq.com> Date: Mon, 20 May 2019 02:14:46 +0800 Subject: [PATCH] fix linkedlist --- list/linkedlist/linkedlist.go | 110 ++++++++++++++++++++++++----- list/linkedlist/linkedlist_test.go | 56 ++++++++++++++- 2 files changed, 147 insertions(+), 19 deletions(-) diff --git a/list/linkedlist/linkedlist.go b/list/linkedlist/linkedlist.go index d548df3..f08a94d 100644 --- a/list/linkedlist/linkedlist.go +++ b/list/linkedlist/linkedlist.go @@ -121,6 +121,34 @@ func (l *LinkedList) Back() (result interface{}, found bool) { 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{}) { if idx > l.size { return @@ -196,33 +224,81 @@ func (l *LinkedList) Insert(idx uint, values ...interface{}) { 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 { panic(fmt.Sprintf("out of list range, size is %d, idx is %d", l.size, idx)) } - if l.head != nil { - if idx == 0 { - l.size-- - temp := l.head - l.head = l.head.next - nodePool.Put(temp) - return + + if idx > l.size/2 { + idx = l.size - 1 - idx + // 尾部 + for cur := l.tail.prev; cur != nil; cur = cur.prev { + if idx == 0 { + 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 { - if idx == 1 { - l.size-- - result := cur.next - cur.next = result.next - result.next = nil - nodePool.Put(result) - return + } else { + // 头部 + for cur := l.head.next; cur != nil; cur = cur.next { + if idx == 0 { + curPrev := cur.prev + curNext := cur.next + curPrev.next = curNext + curNext.prev = curPrev + cur.prev = nil + cur.next = nil + return cur.value, true + } idx-- } } - return + panic(fmt.Sprintf("unknown error")) } func (l *LinkedList) Values() (result []interface{}) { diff --git a/list/linkedlist/linkedlist_test.go b/list/linkedlist/linkedlist_test.go index 79286cc..9a18cbe 100644 --- a/list/linkedlist/linkedlist_test.go +++ b/list/linkedlist/linkedlist_test.go @@ -45,7 +45,7 @@ func TestPushBack(t *testing.T) { func TestPopFront(t *testing.T) { l := New() - // "[0 1 2 3 4]" + // "[4 3 2 1 0]" for i := 0; i < 5; i++ { l.PushFront(i) } @@ -68,7 +68,7 @@ func TestPopFront(t *testing.T) { func TestPopBack(t *testing.T) { l := New() - // "[0 1 2 3 4]" + // "[4 3 2 1 0]" for i := 0; i < 5; 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]" { 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) {