Minor changes to core:slice/heap; add to examples/all

This commit is contained in:
gingerBill
2022-06-12 17:25:42 +01:00
parent 1acc8f438b
commit ff9d058392
2 changed files with 26 additions and 24 deletions
+24 -24
View File
@@ -23,14 +23,14 @@ package heap
The comparator compares elements of type T and can be used to construct a The comparator compares elements of type T and can be used to construct a
max heap (less than) or min heap (greater than) for T. max heap (less than) or min heap (greater than) for T.
*/ */
make :: proc(data: []$T, compare: $C) { make :: proc(data: []$T, less: proc(a, b: T) -> bool) {
// amoritize length lookup // amoritize length lookup
length := len(data) length := len(data)
if length <= 1 do return if length <= 1 do return
// start from data parent, no need to consider children // start from data parent, no need to consider children
for start := (length - 2) / 2; start >= 0; start -= 1 { for start := (length - 2) / 2; start >= 0; start -= 1 {
sift_down(data, compare, start) sift_down(data, less, start)
} }
} }
@@ -40,8 +40,8 @@ make :: proc(data: []$T, compare: $C) {
At most log(N) comparisons where N = len(data) will be performed. At most log(N) comparisons where N = len(data) will be performed.
*/ */
push :: proc(data: []$T, compare: $C) { push :: proc(data: []$T, less: proc(a, b: T) -> bool) {
sift_up(data, compare) sift_up(data, less)
} }
/* /*
@@ -51,7 +51,7 @@ push :: proc(data: []$T, compare: $C) {
At most 2 * log(N) comparisons where N = len(data) will be performed. At most 2 * log(N) comparisons where N = len(data) will be performed.
*/ */
pop :: proc(data: []$T, compare: $C) { pop :: proc(data: []$T, less: proc(a, b: T) -> bool) {
length := len(data) length := len(data)
if length <= 1 do return if length <= 1 do return
@@ -59,7 +59,7 @@ pop :: proc(data: []$T, compare: $C) {
// create a hole at 0 // create a hole at 0
top := data[0] top := data[0]
hole := floyd_sift_down(data, compare) hole := floyd_sift_down(data, less)
last -= 1 last -= 1
if hole == last { if hole == last {
@@ -68,7 +68,7 @@ pop :: proc(data: []$T, compare: $C) {
data[hole] = data[last] data[hole] = data[last]
hole += 1 hole += 1
data[last] = top data[last] = top
sift_up(data[:hole], compare) sift_up(data[:hole], less)
} }
} }
@@ -78,9 +78,9 @@ pop :: proc(data: []$T, compare: $C) {
At most 2 * N * log(N) comparisons where N = len(data) will be performed. At most 2 * N * log(N) comparisons where N = len(data) will be performed.
*/ */
sort :: proc(data: []$T, compare: $C) { sort :: proc(data: []$T, less: proc(a, b: T) -> bool) {
for n := len(data); n >= 1; n -= 1 { for n := len(data); n >= 1; n -= 1 {
pop(data[:n], compare) pop(data[:n], less)
} }
} }
@@ -93,16 +93,16 @@ sort :: proc(data: []$T, compare: $C) {
At most O(n) comparisons where N = len(data) will be performed. At most O(n) comparisons where N = len(data) will be performed.
*/ */
is_heap_until :: proc(data: []$T, compare: $C) -> int { is_heap_until :: proc(data: []$T, less: proc(a, b: T) -> bool) -> int {
length := len(data) length := len(data)
a := 0 a := 0
b := 1 b := 1
for b < length { for b < length {
if compare(data[a], data[b]) { if less(data[a], data[b]) {
return b return b
} }
b += 1 b += 1
if b == length || compare(data[a], data[b]) { if b == length || less(data[a], data[b]) {
return b return b
} }
a += 1 a += 1
@@ -116,12 +116,12 @@ is_heap_until :: proc(data: []$T, compare: $C) -> int {
At most O(n) comparisons where N = len(data) will be performed. At most O(n) comparisons where N = len(data) will be performed.
*/ */
is_heap :: #force_inline proc(data: []$T, compare: $C) -> bool { is_heap :: #force_inline proc(data: []$T, less: proc(a, b: T) -> bool) -> bool {
return is_heap_until(data, compare) == len(data) return is_heap_until(data, less) == len(data)
} }
@(private="file") @(private="file")
floyd_sift_down :: proc(data: []$T, compare: $C) -> int { floyd_sift_down :: proc(data: []$T, less: proc(a, b: T) -> bool) -> int {
length := len(data) length := len(data)
assert(length >= 2) assert(length >= 2)
@@ -131,7 +131,7 @@ floyd_sift_down :: proc(data: []$T, compare: $C) -> int {
for { for {
index += child + 1 index += child + 1
child = 2 * child + 1 child = 2 * child + 1
if child + 1 < length && compare(data[index], data[index + 1]) { if child + 1 < length && less(data[index], data[index + 1]) {
child += 1 child += 1
index += 1 index += 1
} }
@@ -148,7 +148,7 @@ floyd_sift_down :: proc(data: []$T, compare: $C) -> int {
} }
@(private="file") @(private="file")
sift_down :: proc(data: []$T, compare: $C, start: int) { sift_down :: proc(data: []$T, less: proc(a, b: T) -> bool, start: int) {
start := start start := start
child := start child := start
@@ -163,13 +163,13 @@ sift_down :: proc(data: []$T, compare: $C, start: int) {
child = 2 * child + 1 child = 2 * child + 1
if child + 1 < length && compare(data[child], data[child + 1]) { if child + 1 < length && less(data[child], data[child + 1]) {
// right child exists and is greater than left child // right child exists and is greater than left child
child += 1 child += 1
} }
// check if in heap order // check if in heap order
if compare(data[child], data[start]) { if less(data[child], data[start]) {
// start is larger than its largest child // start is larger than its largest child
return return
} }
@@ -187,13 +187,13 @@ sift_down :: proc(data: []$T, compare: $C, start: int) {
// recompute child based off updated parent // recompute child based off updated parent
child = 2 * child + 1 child = 2 * child + 1
if child + 1 < length && compare(data[child], data[child + 1]) { if child + 1 < length && less(data[child], data[child + 1]) {
// right child exists and is greater than left child // right child exists and is greater than left child
child += 1 child += 1
} }
// check if we are in heap order // check if we are in heap order
if compare(data[child], top) { if less(data[child], top) {
break break
} }
} }
@@ -202,7 +202,7 @@ sift_down :: proc(data: []$T, compare: $C, start: int) {
} }
@(private="file") @(private="file")
sift_up :: proc(data: []$T, compare: $C) { sift_up :: proc(data: []$T, less: proc(a, b: T) -> bool) {
// amoritize length lookup // amoritize length lookup
length := len(data) length := len(data)
@@ -212,7 +212,7 @@ sift_up :: proc(data: []$T, compare: $C) {
length = (length - 2) / 2 length = (length - 2) / 2
index := length index := length
last -= 1 last -= 1
if compare(data[index], data[last]) { if less(data[index], data[last]) {
top := data[last] top := data[last]
for { for {
data[last] = data[index] data[last] = data[index]
@@ -222,7 +222,7 @@ sift_up :: proc(data: []$T, compare: $C) {
} }
length = (length - 1) / 2 length = (length - 1) / 2
index = length index = length
if !compare(data[index], top) { if !less(data[index], top) {
break break
} }
} }
+2
View File
@@ -98,6 +98,7 @@ import reflect "core:reflect"
import runtime "core:runtime" import runtime "core:runtime"
import simd "core:simd" import simd "core:simd"
import slice "core:slice" import slice "core:slice"
import slice_heap "core:slice/heap"
import sort "core:sort" import sort "core:sort"
import strconv "core:strconv" import strconv "core:strconv"
import strings "core:strings" import strings "core:strings"
@@ -195,6 +196,7 @@ _ :: reflect
_ :: runtime _ :: runtime
_ :: simd _ :: simd
_ :: slice _ :: slice
_ :: slice_heap
_ :: sort _ :: sort
_ :: strconv _ :: strconv
_ :: strings _ :: strings