fix some linkedlist bug
This commit is contained in:
parent
632a3bd3ab
commit
2b79a1acab
|
@ -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{}) {
|
||||
|
|
|
@ -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>" {
|
||||
|
|
Loading…
Reference in New Issue
Block a user