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
}
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) {
if idx >= l.size {
return nil, false
@ -129,7 +160,7 @@ func (l *LinkedList) Index(idx uint) (interface{}, bool) {
if idx > l.size/2 {
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 {
return cur.value, true
}
@ -138,7 +169,7 @@ func (l *LinkedList) Index(idx uint) (interface{}, bool) {
} 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 {
return cur.value, true
}
@ -258,11 +289,10 @@ func (l *LinkedList) InsertIf(every func(idx uint, value interface{}) int, value
end.next = cnext
}
l.size += uint(len(values))
break
}
}
l.size += uint(len(values))
}
func remove(cur *Node) {
@ -283,7 +313,7 @@ func (l *LinkedList) Remove(idx uint) (interface{}, bool) {
if idx > l.size/2 {
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 {
remove(cur)
return cur.value, true
@ -293,7 +323,7 @@ func (l *LinkedList) Remove(idx uint) (interface{}, bool) {
} 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 {
remove(cur)
return cur.value, true
@ -306,16 +336,27 @@ func (l *LinkedList) Remove(idx uint) (interface{}, bool) {
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 {
if every(cur.value) {
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
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{}) {

View File

@ -199,6 +199,117 @@ func TestInsertIf(t *testing.T) {
// 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) {
l := New()
// "[4 3 2 1 0]"
@ -290,26 +401,26 @@ func TestRemoveIf(t *testing.T) {
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 {
return true
return 1
}
return false
return 0
}); ok {
if r != 0 {
if result[0] != 0 {
t.Error("result should is", 0)
}
} else {
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 {
return true
return 1
}
return false
return 0
}); ok {
if r != 4 {
if result[0] != 4 {
t.Error("result should is", 4)
}
} else {
@ -322,15 +433,15 @@ func TestRemoveIf(t *testing.T) {
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 {
return true
return 1
}
return false
return 0
}); ok {
t.Error("should not be ok and result is nil")
} else {
if r != nil {
if result != 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)
}
for _, v := range l.Values() {
l.RemoveIf(func(value interface{}) bool {
if value == v {
return true
}
return false
})
}
l.RemoveIf(func(idx uint, value interface{}) int {
if value == 3 || value == 2 || value == 1 {
return 1
}
return 0
})
result = spew.Sprint(l.Values())
if result != "<nil>" {