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
|
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{}) {
|
||||||
|
@ -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 false
|
return 0
|
||||||
})
|
})
|
||||||
}
|
|
||||||
|
|
||||||
result = spew.Sprint(l.Values())
|
result = spew.Sprint(l.Values())
|
||||||
if result != "<nil>" {
|
if result != "<nil>" {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user