mirror of
https://github.com/duke-git/lancet.git
synced 2026-02-15 10:12:29 +08:00
feat: add some functons of singlelink
This commit is contained in:
13
datastructure/linknode.go
Normal file
13
datastructure/linknode.go
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package datastructure
|
||||||
|
|
||||||
|
// LinkNode is a linkedlist node, which have a value and Pre points to previous node, Next points to a next node of the link.
|
||||||
|
type LinkNode[T any] struct {
|
||||||
|
Value T
|
||||||
|
Pre *LinkNode[T]
|
||||||
|
Next *LinkNode[T]
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewLinkNode[T any](value T) *LinkNode[T] {
|
||||||
|
return &LinkNode[T]{value, nil, nil}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,12 +1,103 @@
|
|||||||
package datastructure
|
package datastructure
|
||||||
|
|
||||||
// Node is a linkedlist node, which have a value and Pre points to previous node, Next points to a next node of the link.
|
import (
|
||||||
type Node[T any] struct {
|
"errors"
|
||||||
Value T
|
"fmt"
|
||||||
Pre *Node[T]
|
)
|
||||||
Next *Node[T]
|
|
||||||
|
// SinglyLink is a linkedlist of node, which have a value and Pre points to previous node, Next points to a next node of the link.
|
||||||
|
type SinglyLink[T any] struct {
|
||||||
|
Head *LinkNode[T]
|
||||||
|
length int
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewNode[T any](value T) *Node[T] {
|
// NewSinglyLink return *SinglyLink instance
|
||||||
return &Node[T]{value, nil, nil}
|
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)
|
||||||
|
newNode.Next = link.Head
|
||||||
|
link.Head = newNode
|
||||||
|
link.length++
|
||||||
|
}
|
||||||
|
|
||||||
|
// InsertAtTail insert value into singly linklist at tail index
|
||||||
|
func (link *SinglyLink[T]) InsertAtTail(value T) {
|
||||||
|
current := link.Head
|
||||||
|
if current == nil {
|
||||||
|
link.InsertAtHead(value)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for current.Next != nil {
|
||||||
|
current = current.Next
|
||||||
|
}
|
||||||
|
|
||||||
|
newNode := NewLinkNode(value)
|
||||||
|
newNode.Next = nil
|
||||||
|
current.Next = newNode
|
||||||
|
|
||||||
|
link.length++
|
||||||
|
}
|
||||||
|
|
||||||
|
// InsertAt insert value into singly linklist at index
|
||||||
|
func (link *SinglyLink[T]) InsertAt(index int, value T) error {
|
||||||
|
size := link.length
|
||||||
|
if index < 0 || index > size {
|
||||||
|
return errors.New("param index should between 0 and the length of singly link.")
|
||||||
|
}
|
||||||
|
|
||||||
|
if index == 0 {
|
||||||
|
link.InsertAtHead(value)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if index == size {
|
||||||
|
link.InsertAtTail(value)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
i := 0
|
||||||
|
current := link.Head
|
||||||
|
|
||||||
|
for current != nil {
|
||||||
|
if i == index-1 {
|
||||||
|
newNode := NewLinkNode(value)
|
||||||
|
newNode.Next = current.Next
|
||||||
|
current.Next = newNode
|
||||||
|
link.length++
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
current = current.Next
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors.New("singly link no exist")
|
||||||
}
|
}
|
||||||
|
|||||||
62
datastructure/singlylink_test.go
Normal file
62
datastructure/singlylink_test.go
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
package datastructure
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/duke-git/lancet/internal"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSinglyLink_InsertAtFirst(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestSinglyLink_InsertAtFirst")
|
||||||
|
|
||||||
|
link := NewSinglyLink[int]()
|
||||||
|
link.InsertAtHead(1)
|
||||||
|
link.InsertAtHead(2)
|
||||||
|
link.InsertAtHead(3)
|
||||||
|
link.Print()
|
||||||
|
|
||||||
|
expected := []int{3, 2, 1}
|
||||||
|
values := link.Values()
|
||||||
|
|
||||||
|
assert.Equal(expected, values)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSinglyLink_InsertAtTail(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestSinglyLink_InsertAtTail")
|
||||||
|
|
||||||
|
link := NewSinglyLink[int]()
|
||||||
|
link.InsertAtTail(1)
|
||||||
|
link.InsertAtTail(2)
|
||||||
|
link.InsertAtTail(3)
|
||||||
|
link.Print()
|
||||||
|
|
||||||
|
expected := []int{1, 2, 3}
|
||||||
|
values := link.Values()
|
||||||
|
|
||||||
|
assert.Equal(expected, values)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSinglyLink_InsertAt(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestSinglyLink_InsertAt")
|
||||||
|
|
||||||
|
link := NewSinglyLink[int]()
|
||||||
|
|
||||||
|
err := link.InsertAt(1, 1)
|
||||||
|
assert.IsNotNil(err)
|
||||||
|
|
||||||
|
err = link.InsertAt(0, 1)
|
||||||
|
err = link.InsertAt(1, 2)
|
||||||
|
err = link.InsertAt(2, 4)
|
||||||
|
err = link.InsertAt(2, 3)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
link.Print()
|
||||||
|
|
||||||
|
expected := []int{1, 2, 3, 4}
|
||||||
|
values := link.Values()
|
||||||
|
|
||||||
|
assert.Equal(expected, values)
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user