fix some linkedlist bug

This commit is contained in:
huangsimin 2019-05-21 14:28:08 +08:00
parent 632a3bd3ab
commit 2b79a1acab
2 changed files with 182 additions and 32 deletions

View File

@ -121,6 +121,37 @@ func (l *LinkedList) Back() (result interface{}, found bool) {
return nil, false return nil, false
} }
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
}
func (l *LinkedList) Index(idx uint) (interface{}, bool) { func (l *LinkedList) Index(idx uint) (interface{}, bool) {
if idx >= l.size { if idx >= l.size {
return nil, false return nil, false
@ -129,7 +160,7 @@ func (l *LinkedList) Index(idx uint) (interface{}, bool) {
if idx > l.size/2 { if idx > l.size/2 {
idx = l.size - 1 - idx idx = l.size - 1 - idx
// 尾部 // 尾部
for cur := l.tail.prev; cur != nil; cur = cur.prev { for cur := l.tail.prev; cur != l.head; cur = cur.prev {
if idx == 0 { if idx == 0 {
return cur.value, true return cur.value, true
} }
@ -138,7 +169,7 @@ func (l *LinkedList) Index(idx uint) (interface{}, bool) {
} else { } else {
// 头部 // 头部
for cur := l.head.next; cur != nil; cur = cur.next { for cur := l.head.next; cur != l.tail; cur = cur.next {
if idx == 0 { if idx == 0 {
return cur.value, true return cur.value, true
} }
@ -258,11 +289,10 @@ func (l *LinkedList) InsertIf(every func(idx uint, value interface{}) int, value
end.next = cnext end.next = cnext
} }
l.size += uint(len(values))
break break
} }
} }
l.size += uint(len(values))
} }
func remove(cur *Node) { func remove(cur *Node) {
@ -283,7 +313,7 @@ func (l *LinkedList) Remove(idx uint) (interface{}, bool) {
if idx > l.size/2 { if idx > l.size/2 {
idx = l.size - idx // l.size - 1 - idx, 先减size idx = l.size - idx // l.size - 1 - idx, 先减size
// 尾部 // 尾部
for cur := l.tail.prev; cur != nil; cur = cur.prev { for cur := l.tail.prev; cur != l.head; cur = cur.prev {
if idx == 0 { if idx == 0 {
remove(cur) remove(cur)
return cur.value, true return cur.value, true
@ -293,7 +323,7 @@ func (l *LinkedList) Remove(idx uint) (interface{}, bool) {
} else { } else {
// 头部 // 头部
for cur := l.head.next; cur != nil; cur = cur.next { for cur := l.head.next; cur != l.tail; cur = cur.next {
if idx == 0 { if idx == 0 {
remove(cur) remove(cur)
return cur.value, true return cur.value, true
@ -306,16 +336,27 @@ func (l *LinkedList) Remove(idx uint) (interface{}, bool) {
panic(fmt.Sprintf("unknown error")) panic(fmt.Sprintf("unknown error"))
} }
func (l *LinkedList) RemoveIf(every func(value interface{}) bool) (interface{}, bool) { func (l *LinkedList) RemoveIf(every func(idx uint, value interface{}) int) (result []interface{}, isRemoved bool) {
// 头部 // 头部
for cur := l.head.next; cur != nil; cur = cur.next { idx := uint(0)
if every(cur.value) { 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
remove(cur) remove(cur)
return cur.value, true cur = temp
l.size--
continue
case j < 0:
return
} }
}
return nil, false cur = cur.next
}
return
} }
func (l *LinkedList) Values() (result []interface{}) { func (l *LinkedList) Values() (result []interface{}) {

View File

@ -199,6 +199,117 @@ func TestInsertIf(t *testing.T) {
// t.Error(l.Values()) // t.Error(l.Values())
} }
func TestFind(t *testing.T) {
l := New()
// "[4 3 2 1 0]"
for i := 0; i < 5; i++ {
l.PushFront(i)
}
if v, isfound := l.Find(func(idx uint, value interface{}) bool {
if idx == 1 {
return true
}
return false
}); isfound {
if v != 3 {
t.Error("[4 3 2 1 0] index 1 shoud be 3 but value is", v)
}
} else {
t.Error("should be found")
}
if v, isfound := l.Find(func(idx uint, value interface{}) bool {
if idx == 5 {
return true
}
return false
}); isfound {
t.Error("should not be found, but v is found, ", v)
}
}
func TestFindMany(t *testing.T) {
l := New()
// "[4 3 2 1 0]"
for i := 0; i < 5; i++ {
l.PushFront(i)
}
if values, isfound := l.FindMany(func(idx uint, value interface{}) int {
if idx >= 1 {
return 1
}
return 0
}); isfound {
var result string
result = spew.Sprint(values)
if result != "[3 2 1 0]" {
t.Error("result should be [3 2 1 0], reuslt is", result)
}
} else {
t.Error("should be found")
}
if values, isfound := l.FindMany(func(idx uint, value interface{}) int {
if idx%2 == 0 {
return 1
}
return 0
}); isfound {
var result string
result = spew.Sprint(values)
if result != "[4 2 0]" {
t.Error("result should be [3 2 1 0], reuslt is", result)
}
} else {
t.Error("should be found")
}
if values, isfound := l.FindMany(func(idx uint, value interface{}) int {
if value == 0 || value == 2 || value == 4 || value == 7 {
return 1
}
return 0
}); isfound {
var result string
result = spew.Sprint(values)
if result != "[4 2 0]" {
t.Error("result should be [4 2 0], reuslt is", result)
}
} else {
t.Error("should be found")
}
if values, isfound := l.FindMany(func(idx uint, value interface{}) int {
if value.(int) <= 2 {
return -1
}
if value.(int) <= 4 && value.(int) > 2 {
return 1
}
return 0
}); isfound {
var result string
result = spew.Sprint(values)
if result != "[4 3]" {
t.Error("result should be [4 2 0], reuslt is", result)
}
} else {
t.Error("should be found")
}
// if v, isfound := l.Find(func(idx uint, value interface{}) bool {
// if idx == 5 {
// return true
// }
// return false
// }); isfound {
// t.Error("should not be found, but v is found, ", v)
// }
}
func TestIndex(t *testing.T) { func TestIndex(t *testing.T) {
l := New() l := New()
// "[4 3 2 1 0]" // "[4 3 2 1 0]"
@ -290,26 +401,26 @@ func TestRemoveIf(t *testing.T) {
l.PushFront(i) l.PushFront(i)
} }
if r, ok := l.RemoveIf(func(value interface{}) bool { if result, ok := l.RemoveIf(func(idx uint, value interface{}) int {
if value == 0 { if value == 0 {
return true return 1
} }
return false return 0
}); ok { }); ok {
if r != 0 { if result[0] != 0 {
t.Error("result should is", 0) t.Error("result should is", 0)
} }
} else { } else {
t.Error("should be ok") t.Error("should be ok")
} }
if r, ok := l.RemoveIf(func(value interface{}) bool { if result, ok := l.RemoveIf(func(idx uint, value interface{}) int {
if value == 4 { if value == 4 {
return true return 1
} }
return false return 0
}); ok { }); ok {
if r != 4 { if result[0] != 4 {
t.Error("result should is", 4) t.Error("result should is", 4)
} }
} else { } else {
@ -322,15 +433,15 @@ func TestRemoveIf(t *testing.T) {
t.Error("should be [3 2 1] but result is", result) t.Error("should be [3 2 1] but result is", result)
} }
if r, ok := l.RemoveIf(func(value interface{}) bool { if result, ok := l.RemoveIf(func(idx uint, value interface{}) int {
if value == 4 { if value == 4 {
return true return 1
} }
return false return 0
}); ok { }); ok {
t.Error("should not be ok and result is nil") t.Error("should not be ok and result is nil")
} else { } else {
if r != nil { if result != nil {
t.Error("should be nil") t.Error("should be nil")
} }
} }
@ -340,14 +451,12 @@ func TestRemoveIf(t *testing.T) {
t.Error("should be [3 2 1] but result is", result) t.Error("should be [3 2 1] but result is", result)
} }
for _, v := range l.Values() { l.RemoveIf(func(idx uint, value interface{}) int {
l.RemoveIf(func(value interface{}) bool { if value == 3 || value == 2 || value == 1 {
if value == v { return 1
return true }
} return 0
return false })
})
}
result = spew.Sprint(l.Values()) result = spew.Sprint(l.Values())
if result != "<nil>" { if result != "<nil>" {