126 lines
2.1 KiB
Odin
126 lines
2.1 KiB
Odin
|
package linked_list
|
||
|
import "core:fmt"
|
||
|
|
||
|
node :: struct($Value: typeid) {
|
||
|
data: Value,
|
||
|
next: ^node(Value),
|
||
|
}
|
||
|
|
||
|
to_string :: proc(head: ^node($T)) -> string {
|
||
|
curr := head
|
||
|
out: string
|
||
|
counter := 0
|
||
|
out = fmt.tprintf("[%v]", curr.data)
|
||
|
for curr.next != nil{
|
||
|
curr = curr.next
|
||
|
if counter >= 8 {
|
||
|
out = fmt.tprintf("%s -> ... -> [%v]", out, tail(curr.next))
|
||
|
break
|
||
|
}
|
||
|
out = fmt.tprintf("%s -> [%v]", out, curr.data)
|
||
|
counter += 1
|
||
|
}
|
||
|
|
||
|
return out
|
||
|
}
|
||
|
|
||
|
remove :: proc(head: ^^node($T), value: T) {
|
||
|
curr := head^
|
||
|
pp := head
|
||
|
for curr != nil && curr.data != value {
|
||
|
pp = &curr.next
|
||
|
curr = curr.next
|
||
|
}
|
||
|
|
||
|
if curr == nil do return
|
||
|
|
||
|
pp^ = curr.next
|
||
|
free(curr)
|
||
|
}
|
||
|
|
||
|
remove_all :: proc(head: ^^node($T), value: T) {
|
||
|
curr := head^
|
||
|
pp := head
|
||
|
for {
|
||
|
for curr != nil && curr.data != value {
|
||
|
pp = &curr.next
|
||
|
curr = curr.next
|
||
|
}
|
||
|
if curr != nil {
|
||
|
pp^ = curr.next
|
||
|
free(curr)
|
||
|
curr = pp^
|
||
|
} else {
|
||
|
return
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
prepend_value :: proc(head: ^^node($T), value: T) -> ^node(T) {
|
||
|
n := prepend(head)
|
||
|
n.data = value
|
||
|
return n
|
||
|
}
|
||
|
|
||
|
prepend :: proc(head: ^^node($T)) -> ^node(T) {
|
||
|
n := new(node(T))
|
||
|
n.next = head^
|
||
|
head^ = n
|
||
|
return n
|
||
|
}
|
||
|
|
||
|
append_value :: proc(head: ^node($T), value: T) -> ^node(T) {
|
||
|
n := append(head)
|
||
|
n.data = value
|
||
|
return n
|
||
|
}
|
||
|
|
||
|
append :: proc(head: ^node($T)) -> ^node(T) {
|
||
|
curr := head
|
||
|
for curr.next != nil {
|
||
|
curr = curr.next
|
||
|
}
|
||
|
curr.next = new(node(T))
|
||
|
return curr.next
|
||
|
}
|
||
|
|
||
|
head :: proc(h: ^node($T)) -> T {
|
||
|
return h.data
|
||
|
}
|
||
|
|
||
|
tail :: proc(head: ^node($T)) -> T {
|
||
|
curr := head
|
||
|
for curr.next != nil {
|
||
|
curr = curr.next
|
||
|
}
|
||
|
return curr.data
|
||
|
}
|
||
|
|
||
|
// counting starts from 0
|
||
|
nth :: proc(head: ^node($T), n: u64) -> T {
|
||
|
curr := head
|
||
|
counter := 0
|
||
|
for curr != nil {
|
||
|
if counter == n {
|
||
|
return curr.data
|
||
|
}
|
||
|
curr = curr.next
|
||
|
counter += 1
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
deinit :: proc(head: ^node($T)) {
|
||
|
curr := head
|
||
|
next: ^node(T)
|
||
|
for curr != nil {
|
||
|
next = curr.next
|
||
|
free(curr)
|
||
|
curr = next
|
||
|
}
|
||
|
}
|
||
|
|
||
|
init :: proc($T: typeid) -> (head: ^node(T)) {
|
||
|
return new(node(T))
|
||
|
}
|