From 5ab150cad32f95ee4b6b12137896dd8bb07af09f Mon Sep 17 00:00:00 2001 From: dudaodong Date: Thu, 3 Feb 2022 16:37:34 +0800 Subject: [PATCH] feat: add DeleteAtHead, DeleteAtTail, DeleteAt, Reverse, Size, GetMiddleNode funcs in singlelink --- datastructure/singlylink.go | 156 ++++++++++++++++++++++++++----- datastructure/singlylink_test.go | 103 ++++++++++++++++++++ 2 files changed, 235 insertions(+), 24 deletions(-) diff --git a/datastructure/singlylink.go b/datastructure/singlylink.go index ed758e8..f63d601 100644 --- a/datastructure/singlylink.go +++ b/datastructure/singlylink.go @@ -16,29 +16,6 @@ func NewSinglyLink[T any]() *SinglyLink[T] { return &SinglyLink[T]{Head: nil} } -// Values return slice of all singly linklist node value -func (link *SinglyLink[T]) Values() []T { - res := []T{} - current := link.Head - for current != nil { - res = append(res, current.Value) - current = current.Next - } - return res -} - -// Print all nodes info of a linked list -func (link *SinglyLink[T]) Print() { - current := link.Head - info := "[ " - for current != nil { - info += fmt.Sprintf("%+v, ", current) - current = current.Next - } - info += " ]" - fmt.Println(info) -} - // InsertAtHead insert value into singly linklist at head index func (link *SinglyLink[T]) InsertAtHead(value T) { newNode := NewLinkNode(value) @@ -99,5 +76,136 @@ func (link *SinglyLink[T]) InsertAt(index int, value T) error { current = current.Next } - return errors.New("singly link no exist") + return errors.New("singly link list no exist") +} + +// DeleteAtHead delete value in singly linklist at head index +func (link *SinglyLink[T]) DeleteAtHead() error { + if link.Head == nil { + return errors.New("singly link list no exist") + } + current := link.Head + link.Head = current.Next + link.length-- + + return nil +} + +// DeleteAtTail delete value in singly linklist at tail index +func (link *SinglyLink[T]) DeleteAtTail() error { + if link.Head == nil { + return errors.New("singly link list no exist") + } + current := link.Head + if current.Next == nil { + return link.DeleteAtHead() + } + + for current.Next.Next != nil { + current = current.Next + } + + current.Next = nil + link.length-- + return nil +} + +// DeleteAt delete value in singly linklist at index +func (link *SinglyLink[T]) DeleteAt(index int) error { + if link.Head == nil { + return errors.New("singly link list no exist") + } + current := link.Head + if current.Next == nil || index == 0 { + return link.DeleteAtHead() + } + + if index == link.length-1 { + return link.DeleteAtTail() + } + + if index < 0 || index > link.length-1 { + return errors.New("param index should between 0 and link size -1.") + } + + i := 0 + for current != nil { + if i == index-1 { + current.Next = current.Next.Next + link.length-- + return nil + } + i++ + current = current.Next + } + + return errors.New("delete error") +} + +// Reverse the linked list +func (link *SinglyLink[T]) Reverse() { + var pre, next *LinkNode[T] + + current := link.Head + + for current != nil { + next = current.Next + current.Next = pre + pre = current + current = next + } + + link.Head = pre +} + +// GetMiddleNode return node at middle index of linked list +func (link *SinglyLink[T]) GetMiddleNode() *LinkNode[T] { + if link.Head == nil { + return nil + } + if link.Head.Next == nil { + return link.Head + } + fast := link.Head + slow := link.Head + + for fast != nil { + fast = fast.Next + + if fast != nil { + fast = fast.Next + slow = slow.Next + } else { + return slow + } + } + return slow +} + +// Size return the count of singly linked list +func (link *SinglyLink[T]) Size() int { + return link.length +} + +// Values return slice of all singly linklist node value +func (link *SinglyLink[T]) Values() []T { + res := []T{} + current := link.Head + for current != nil { + res = append(res, current.Value) + current = current.Next + } + return res +} + +// Print all nodes info of a linked list +func (link *SinglyLink[T]) Print() { + current := link.Head + info := "[ " + for current != nil { + info += fmt.Sprintf("%+v, ", current) + current = current.Next + } + info += " ]" + fmt.Println(info) } diff --git a/datastructure/singlylink_test.go b/datastructure/singlylink_test.go index 4322594..5c813fe 100644 --- a/datastructure/singlylink_test.go +++ b/datastructure/singlylink_test.go @@ -60,3 +60,106 @@ func TestSinglyLink_InsertAt(t *testing.T) { assert.Equal(expected, values) } + +func TestSinglyLink_DeleteAtHead(t *testing.T) { + assert := internal.NewAssert(t, "TestSinglyLink_DeleteAtHead") + + link := NewSinglyLink[int]() + err := link.DeleteAtHead() + assert.IsNotNil(err) + + link.InsertAtTail(1) + link.InsertAtTail(2) + link.InsertAtTail(3) + link.InsertAtTail(4) + + link.DeleteAtHead() + link.Print() + + expected := []int{2, 3, 4} + values := link.Values() + + assert.Equal(expected, values) +} + +func TestSinglyLink_DeleteAtTail(t *testing.T) { + assert := internal.NewAssert(t, "TestSinglyLink_DeleteAtTail") + + link := NewSinglyLink[int]() + err := link.DeleteAtTail() + assert.IsNotNil(err) + + link.InsertAtTail(1) + link.InsertAtTail(2) + link.InsertAtTail(3) + link.InsertAtTail(4) + + link.DeleteAtTail() + link.Print() + + expected := []int{1, 2, 3} + values := link.Values() + + assert.Equal(expected, values) +} + +func TestSinglyLink_DeleteAt(t *testing.T) { + assert := internal.NewAssert(t, "TestSinglyLink_DeleteAt") + + link := NewSinglyLink[int]() + err := link.DeleteAt(0) + assert.IsNotNil(err) + + link.InsertAtTail(1) + link.InsertAtTail(2) + link.InsertAtTail(3) + link.InsertAtTail(4) + link.InsertAtTail(5) + + err = link.DeleteAt(5) + assert.IsNotNil(err) + + err = link.DeleteAt(0) + assert.IsNil(err) + assert.Equal([]int{2, 3, 4, 5}, link.Values()) + + link.DeleteAt(3) + assert.Equal([]int{2, 3, 4}, link.Values()) + + link.DeleteAt(1) + assert.Equal(2, link.Size()) + assert.Equal([]int{2, 4}, link.Values()) +} + +func TestSinglyLink_Reverse(t *testing.T) { + assert := internal.NewAssert(t, "TestSinglyLink_Reverse") + + link := NewSinglyLink[int]() + link.InsertAtTail(1) + link.InsertAtTail(2) + link.InsertAtTail(3) + link.InsertAtTail(4) + + link.Reverse() + link.Print() + assert.Equal([]int{4, 3, 2, 1}, link.Values()) +} + +func TestSinglyLink_GetMiddleNode(t *testing.T) { + assert := internal.NewAssert(t, "TestSinglyLink_GetMiddleNode") + + link := NewSinglyLink[int]() + link.InsertAtTail(1) + link.InsertAtTail(2) + link.InsertAtTail(3) + link.InsertAtTail(4) + + middle1 := link.GetMiddleNode() + assert.Equal(3, middle1.Value) + + link.InsertAtTail(5) + link.InsertAtTail(6) + link.InsertAtTail(7) + middle2 := link.GetMiddleNode() + assert.Equal(4, middle2.Value) +}