Skip to content

Commit

Permalink
fix: fix impl
Browse files Browse the repository at this point in the history
  • Loading branch information
thinkgos committed Jul 1, 2024
1 parent a0e53b5 commit 89c3d65
Show file tree
Hide file tree
Showing 28 changed files with 1,188 additions and 662 deletions.
165 changes: 82 additions & 83 deletions arraylist/array_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ package arraylist

import (
"fmt"

"slices"

"github.com/things-go/container"
Expand All @@ -38,203 +37,203 @@ func New[T comparable]() *List[T] {

// Len returns the number of elements of list l.
// The complexity is O(1).
func (sf *List[T]) Len() int { return len(sf.items) }
func (l *List[T]) Len() int { return len(l.items) }

// IsEmpty returns the list l is empty or not.
func (sf *List[T]) IsEmpty() bool { return sf.Len() == 0 }
func (l *List[T]) IsEmpty() bool { return l.Len() == 0 }

// Clear initializes or clears list l.
func (sf *List[T]) Clear() { sf.items = make([]T, 0) }
func (l *List[T]) Clear() { l.items = make([]T, 0) }

// Push inserts a new element e with value v at the back of list l.
func (sf *List[T]) Push(items T) { sf.items = append(sf.items, items) }
func (l *List[T]) Push(items T) { l.items = append(l.items, items) }

// PushFront inserts a new element e with value v at the front of list l.
func (sf *List[T]) PushFront(v T) {
sf.items = append(sf.items, v)
moveLastToFirst(sf.items)
func (l *List[T]) PushFront(v T) {
l.items = append(l.items, v)
moveLastToFirst(l.items)
}

// PushBack inserts a new element e with value v at the back of list l.
func (sf *List[T]) PushBack(v T) { sf.items = append(sf.items, v) }
func (l *List[T]) PushBack(v T) { l.items = append(l.items, v) }

// Add inserts the specified element at the specified position in this list.
func (sf *List[T]) Add(index int, val T) error {
if index < 0 || index > len(sf.items) {
return fmt.Errorf("index out of range, index: %d, len: %d", index, sf.Len())
func (l *List[T]) Add(index int, val T) error {
if index < 0 || index > len(l.items) {
return fmt.Errorf("index out of range, index: %d, len: %d", index, l.Len())
}

if index == sf.Len() {
sf.Push(val)
if index == l.Len() {
l.Push(val)
} else {
length := len(sf.items)
sf.items = append(sf.items, val)
copy(sf.items[index+1:], sf.items[index:length])
sf.items[index] = val
length := len(l.items)
l.items = append(l.items, val)
copy(l.items[index+1:], l.items[index:length])
l.items[index] = val
}
return nil
}

// PushFrontList inserts a copy of an other list at the front of list l.
// The lists l and other may be the same. They must not be nil.
func (sf *List[T]) PushFrontList(other *List[T]) {
items := make([]T, 0, len(sf.items)+len(other.items))
func (l *List[T]) PushFrontList(other *List[T]) {
items := make([]T, 0, len(l.items)+len(other.items))
items = append(items, other.items...)
items = append(items, sf.items...)
sf.items = items
items = append(items, l.items...)
l.items = items
}

// PushBackList inserts a copy of an other list at the back of list l.
// The lists l and other may be the same. They must not be nil.
func (sf *List[T]) PushBackList(other *List[T]) {
sf.items = append(sf.items, other.items...)
func (l *List[T]) PushBackList(other *List[T]) {
l.items = append(l.items, other.items...)
}

// Poll return the front element value and then remove from list.
func (sf *List[T]) Poll() (val T, ok bool) {
return sf.PollFront()
func (l *List[T]) Poll() (val T, ok bool) {
return l.PollFront()
}

// PollFront return the front element value and then remove from list.
func (sf *List[T]) PollFront() (val T, ok bool) {
func (l *List[T]) PollFront() (val T, ok bool) {
var placeholder T

if n := len(sf.items); n > 0 {
moveFirstToLast(sf.items)
val = sf.items[n-1]
sf.items[n-1] = placeholder // for gc
sf.items = sf.items[:n-1]
if n := len(l.items); n > 0 {
moveFirstToLast(l.items)
val = l.items[n-1]
l.items[n-1] = placeholder // for gc
l.items = l.items[:n-1]
ok = true
}
return val, ok
}

// PollBack return the back element value and then remove from list.
func (sf *List[T]) PollBack() (val T, ok bool) {
func (l *List[T]) PollBack() (val T, ok bool) {
var placeholder T

if n := len(sf.items); n > 0 {
val = sf.items[n-1]
sf.items[n-1] = placeholder // for gc
sf.items = sf.items[:n-1]
if n := len(l.items); n > 0 {
val = l.items[n-1]
l.items[n-1] = placeholder // for gc
l.items = l.items[:n-1]
ok = true
}
return val, ok
}

// Remove removes the element at the specified position in this list.
// It returns an error if the index is out of range.
func (sf *List[T]) Remove(index int) (val T, err error) {
func (l *List[T]) Remove(index int) (val T, err error) {
var placeholder T

if index < 0 || index >= len(sf.items) {
return val, fmt.Errorf("index out of range, index: %d, len: %d", index, sf.Len())
if index < 0 || index >= len(l.items) {
return val, fmt.Errorf("index out of range, index: %d, len: %d", index, l.Len())
}

val = sf.items[index]
moveFirstToLast(sf.items[index:])
sf.items[len(sf.items)-1] = placeholder
sf.items = sf.items[:len(sf.items)-1]
sf.shrinkList()
val = l.items[index]
moveFirstToLast(l.items[index:])
l.items[len(l.items)-1] = placeholder
l.items = l.items[:len(l.items)-1]
l.shrinkList()
return val, nil
}

// RemoveValue removes the first occurrence of the specified element from this list, if it is present.
// It returns false if the target value isn't present, otherwise returns true.
func (sf *List[T]) RemoveValue(val T) bool {
func (l *List[T]) RemoveValue(val T) bool {
var placeholder T

if sf.Len() == 0 {
if l.Len() == 0 {
return false
}

if idx := sf.indexOf(val); idx >= 0 {
moveFirstToLast(sf.items[idx:])
sf.items[len(sf.items)-1] = placeholder
sf.items = sf.items[:len(sf.items)-1]
sf.shrinkList()
if idx := l.indexOf(val); idx >= 0 {
moveFirstToLast(l.items[idx:])
l.items[len(l.items)-1] = placeholder
l.items = l.items[:len(l.items)-1]
l.shrinkList()
return true
}
return false
}

// Get returns the element at the specified position in this list. The index must be in the range of [0, size).
func (sf *List[T]) Get(index int) (val T, err error) {
if index < 0 || index >= len(sf.items) {
return val, fmt.Errorf("index out of range, index:%d, len:%d", index, sf.Len())
func (l *List[T]) Get(index int) (val T, err error) {
if index < 0 || index >= len(l.items) {
return val, fmt.Errorf("index out of range, index:%d, len:%d", index, l.Len())
}

return sf.items[index], nil
return l.items[index], nil
}

// Peek return the front element value.
func (sf *List[T]) Peek() (val T, ok bool) {
return sf.PeekFront()
func (l *List[T]) Peek() (val T, ok bool) {
return l.PeekFront()
}

// PeekFront return the front element value.
func (sf *List[T]) PeekFront() (val T, ok bool) {
if len(sf.items) > 0 {
return sf.items[0], true
func (l *List[T]) PeekFront() (val T, ok bool) {
if len(l.items) > 0 {
return l.items[0], true
}
return val, false
}

// PeekBack return the back element value.
func (sf *List[T]) PeekBack() (val T, ok bool) {
if len(sf.items) > 0 {
return sf.items[len(sf.items)-1], true
func (l *List[T]) PeekBack() (val T, ok bool) {
if len(l.items) > 0 {
return l.items[len(l.items)-1], true
}
return val, false
}

// Iterator returns an iterator over the elements in this list in proper sequence.
func (sf *List[T]) Iterator(f func(T) bool) {
for index := 0; index < sf.Len(); index++ {
if f == nil || !f(sf.items[index]) {
func (l *List[T]) Iterator(f func(T) bool) {
for index := 0; index < l.Len(); index++ {
if f == nil || !f(l.items[index]) {
return
}
}
}

// ReverseIterator returns an iterator over the elements in this list in reverse sequence as Iterator.
func (sf *List[T]) ReverseIterator(f func(T) bool) {
for index := sf.Len() - 1; index >= 0; index-- {
if f == nil || !f(sf.items[index]) {
func (l *List[T]) ReverseIterator(f func(T) bool) {
for index := l.Len() - 1; index >= 0; index-- {
if f == nil || !f(l.items[index]) {
return
}
}
}

// Contains contains the value.
func (sf *List[T]) Contains(val T) bool {
return sf.indexOf(val) >= 0
func (l *List[T]) Contains(val T) bool {
return l.indexOf(val) >= 0
}

// Sort the list.
func (sf *List[T]) Sort(less func(a, b T) int) {
slices.SortFunc(sf.items, less)
func (l *List[T]) Sort(less func(a, b T) int) {
slices.SortFunc(l.items, less)
}

// Values get a copy of all the values in the list.
func (sf *List[T]) Values() []T {
return slices.Clone(sf.items)
func (l *List[T]) Values() []T {
return slices.Clone(l.items)
}

func (sf *List[T]) shrinkList() {
oldLen, oldCap := len(sf.items), cap(sf.items)
func (l *List[T]) shrinkList() {
oldLen, oldCap := len(l.items), cap(l.items)
if oldCap > 1024 && oldLen <= oldCap/4 { // shrink when len(list) <= cap(list)/4
newItems := make([]T, oldLen)
copy(newItems, sf.items)
sf.Clear()
sf.items = newItems
copy(newItems, l.items)
l.Clear()
l.items = newItems
}
}

// indexOf returns the index of the first occurrence of the specified element
// in this list, or -1 if this list does not contain the element.
func (sf *List[T]) indexOf(val T) int {
for i, v := range sf.items {
func (l *List[T]) indexOf(val T) int {
for i, v := range l.items {
if v == val {
return i
}
Expand Down
14 changes: 7 additions & 7 deletions arraylist/array_list_test.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package arraylist

import (
"slices"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/exp/slices"
)

func TestArrayListLen(t *testing.T) {
func Test_ArrayListLen(t *testing.T) {
l := New[int]()

l.PushBack(5)
Expand All @@ -33,7 +33,7 @@ func TestArrayListLen(t *testing.T) {
assert.True(t, l.IsEmpty())
}

func TestArrayListValue(t *testing.T) {
func Test_ArrayListValue(t *testing.T) {
l := New[int]()
l.Push(5)
l.PushBack(7)
Expand Down Expand Up @@ -134,7 +134,7 @@ func TestArrayListValue(t *testing.T) {
assert.Error(t, err)
}

func TestArrayListIterator(t *testing.T) {
func Test_ArrayListIterator(t *testing.T) {
l := New[int]()
items := []int{5, 6, 7}
l.PushBack(5)
Expand All @@ -149,7 +149,7 @@ func TestArrayListIterator(t *testing.T) {
l.Iterator(nil)
}

func TestArrayListReverseIterator(t *testing.T) {
func Test_ArrayListReverseIterator(t *testing.T) {
items := []int{5, 6, 7}
l := New[int]()
l.PushBack(5)
Expand All @@ -164,7 +164,7 @@ func TestArrayListReverseIterator(t *testing.T) {
l.ReverseIterator(nil)
}

func TestArrayListSort(t *testing.T) {
func Test_ArrayListSort(t *testing.T) {
ll := New[int]()

expect := []int{4, 6, 7, 15}
Expand Down Expand Up @@ -193,7 +193,7 @@ func TestArrayListSort(t *testing.T) {
}
}

func TestExtending(t *testing.T) {
func Test_Extending(t *testing.T) {
l1 := New[int]()
l2 := New[int]()

Expand Down
Loading

0 comments on commit 89c3d65

Please sign in to comment.