diff --git a/README.md b/README.md index 4095445..66dda49 100644 --- a/README.md +++ b/README.md @@ -218,6 +218,8 @@ func main() { _ = list.Size() // 0 list.Add("a") // ["a"] list.Clear() // [] + list.Insert(0, "b") // ["b"] + list.Insert(0, "a") // ["a","b"] } ``` diff --git a/lists/singlylinkedlist/singlylinkedlist.go b/lists/singlylinkedlist/singlylinkedlist.go index a9b4d63..e4730ae 100644 --- a/lists/singlylinkedlist/singlylinkedlist.go +++ b/lists/singlylinkedlist/singlylinkedlist.go @@ -223,6 +223,51 @@ func (list *List) Swap(i, j int) { } } +// Inserts values at specified index position shifting the value at that position (if any) and any subsequent elements to the right. +// Does not do anything if position is negative or bigger than list's size +// Note: position equal to list's size is valid, i.e. append. +func (list *List) Insert(index int, values ...interface{}) { + + if !list.withinRange(index) { + // Append + if index == list.size { + list.Add(values...) + } + fmt.Println(list.Values()) + return + } + + list.size += len(values) + + var beforeElement *element + foundElement := list.first + for e := 0; e != index; e, foundElement = e+1, foundElement.next { + beforeElement = foundElement + } + + if foundElement == list.first { + oldNextElement := list.first + for i, value := range values { + newElement := &element{value: value} + if i == 0 { + list.first = newElement + } else { + beforeElement.next = newElement + } + beforeElement = newElement + } + beforeElement.next = oldNextElement + } else { + oldNextElement := beforeElement.next + for _, value := range values { + newElement := &element{value: value} + beforeElement.next = newElement + beforeElement = newElement + } + beforeElement.next = oldNextElement + } +} + func (list *List) String() string { str := "SinglyLinkedList\n" values := []string{} @@ -235,5 +280,5 @@ func (list *List) String() string { // Check that the index is withing bounds of the list func (list *List) withinRange(index int) bool { - return index >= 0 && index < list.size && list.size != 0 + return index >= 0 && index < list.size } diff --git a/lists/singlylinkedlist/singlylinkedlist_test.go b/lists/singlylinkedlist/singlylinkedlist_test.go index 4956507..df08466 100644 --- a/lists/singlylinkedlist/singlylinkedlist_test.go +++ b/lists/singlylinkedlist/singlylinkedlist_test.go @@ -27,6 +27,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package singlylinkedlist import ( + "fmt" "github.com/emirpasic/gods/utils" "testing" ) @@ -122,6 +123,19 @@ func TestSinglyLinkedList(t *testing.T) { t.Errorf("Got %v expected %v", actualValue, true) } + list.Insert(0, "h") + list.Insert(0, "e") + list.Insert(1, "f") + list.Insert(2, "g") + list.Insert(4, "i") + list.Insert(0, "a", "b") + list.Insert(list.Size(), "j", "k") + list.Insert(2, "c", "d") + + if actualValue, expectedValue := fmt.Sprintf("%s%s%s%s%s%s%s%s%s%s%s", list.Values()...), "abcdefghijk"; actualValue != expectedValue { + t.Errorf("Got %v expected %v", actualValue, expectedValue) + } + } func BenchmarkSinglyLinkedList(b *testing.B) {