From e8ce02b50aa1e2576f818e0e0caa74b5c815c85c Mon Sep 17 00:00:00 2001 From: Odai Alghamdi Date: Fri, 24 Nov 2023 10:40:08 +0300 Subject: [PATCH] datatypes: add push_many for doubly and singly linked list + add insert_many for heap (#19975) --- vlib/datatypes/doubly_linked_list.v | 21 ++++++++++++++++++ vlib/datatypes/doubly_linked_list_test.v | 18 ++++++++++++++++ vlib/datatypes/heap.v | 7 ++++++ vlib/datatypes/heap_test.v | 11 ++++++++++ vlib/datatypes/linked_list.v | 7 ++++++ vlib/datatypes/linked_list_test.v | 11 ++++++++++ vlib/v/checker/tests/cmp_between_struct.out | 24 ++++++++++----------- 7 files changed, 87 insertions(+), 12 deletions(-) diff --git a/vlib/datatypes/doubly_linked_list.v b/vlib/datatypes/doubly_linked_list.v index a4d88ba55f..dc0b533ae5 100644 --- a/vlib/datatypes/doubly_linked_list.v +++ b/vlib/datatypes/doubly_linked_list.v @@ -1,5 +1,10 @@ module datatypes +enum Direction { + front + back +} + struct DoublyListNode[T] { mut: data T @@ -79,6 +84,22 @@ pub fn (mut list DoublyLinkedList[T]) push_front(item T) { list.len += 1 } +// push_many adds array of elements to the beginning of the linked list +pub fn (mut list DoublyLinkedList[T]) push_many(elements []T, direction Direction) { + match direction { + .front { + for v in elements { + list.push_front(v) + } + } + .back { + for v in elements { + list.push_back(v) + } + } + } +} + // pop_back removes the last element of the linked list pub fn (mut list DoublyLinkedList[T]) pop_back() !T { if list.is_empty() { diff --git a/vlib/datatypes/doubly_linked_list_test.v b/vlib/datatypes/doubly_linked_list_test.v index 4fa845cdbf..405605e0bb 100644 --- a/vlib/datatypes/doubly_linked_list_test.v +++ b/vlib/datatypes/doubly_linked_list_test.v @@ -48,6 +48,24 @@ fn test_push() { assert list.last()! == 3 } +fn test_push_many_back() { + mut list := DoublyLinkedList[int]{} + elem := [1, 2, 3] + list.push_many(elem, Direction.back) + assert list.last()! != 1 + assert list.last()! != 2 + assert list.last()! == 3 +} + +fn test_push_many_front() { + mut list := DoublyLinkedList[int]{} + mut elem := [1, 2, 3] + list.push_many(elem, Direction.back) + elem = [111] + list.push_many(elem, Direction.front) + assert list.first()! == 111 +} + fn test_pop() { mut list := DoublyLinkedList[int]{} list.push_back(1) diff --git a/vlib/datatypes/heap.v b/vlib/datatypes/heap.v index 89bc111874..327d5bc639 100644 --- a/vlib/datatypes/heap.v +++ b/vlib/datatypes/heap.v @@ -20,6 +20,13 @@ pub fn (mut heap MinHeap[T]) insert(item T) { } } +// insert array of elements to the heap. +pub fn (mut heap MinHeap[T]) insert_many(elements []T) { + for v in elements { + heap.insert(v) + } +} + // pop removes the top-most element from the heap. pub fn (mut heap MinHeap[T]) pop() !T { if heap.data.len == 0 { diff --git a/vlib/datatypes/heap_test.v b/vlib/datatypes/heap_test.v index 68d65210ac..9422f750a8 100644 --- a/vlib/datatypes/heap_test.v +++ b/vlib/datatypes/heap_test.v @@ -18,6 +18,17 @@ fn test_min_heap() { } } +fn test_min_heap_insert_many() { + mut heap := MinHeap[int]{} + elem := [2, 0, 8, 4, 1] + heap.insert_many(elem) + + assert heap.pop()! == 0 + assert heap.peek()! == 1 + heap.pop()! + assert heap.peek()! == 2 +} + struct Item { data string priority int diff --git a/vlib/datatypes/linked_list.v b/vlib/datatypes/linked_list.v index 2416c78a32..475d839552 100644 --- a/vlib/datatypes/linked_list.v +++ b/vlib/datatypes/linked_list.v @@ -81,6 +81,13 @@ pub fn (mut list LinkedList[T]) push(item T) { list.len += 1 } +// push adds an array of elements to the end of the linked list +pub fn (mut list LinkedList[T]) push_many(elements []T) { + for v in elements { + list.push(v) + } +} + // pop removes the last element of the linked list pub fn (mut list LinkedList[T]) pop() !T { if unsafe { list.head == 0 } { diff --git a/vlib/datatypes/linked_list_test.v b/vlib/datatypes/linked_list_test.v index 8d37b4c310..25ae4ebe3d 100644 --- a/vlib/datatypes/linked_list_test.v +++ b/vlib/datatypes/linked_list_test.v @@ -27,6 +27,17 @@ fn test_first() { assert false } +fn test_push_many() { + mut list := LinkedList[int]{} + x := [1, 2, 3, 4, 5] + list.push_many(x) + assert list.first()! == 1 + assert list.first()! == 1 + list = LinkedList[int]{} + list.first() or { return } + assert false +} + fn test_last() { mut list := LinkedList[int]{} list.push(1) diff --git a/vlib/v/checker/tests/cmp_between_struct.out b/vlib/v/checker/tests/cmp_between_struct.out index 20fd38d169..e08d5ad01b 100644 --- a/vlib/v/checker/tests/cmp_between_struct.out +++ b/vlib/v/checker/tests/cmp_between_struct.out @@ -5,17 +5,17 @@ vlib/datatypes/heap.v:16:15: error: cannot use `>` as `<=` operator method is no | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 17 | heap.data[parent], heap.data[child] = heap.data[child], heap.data[parent] 18 | child = parent -vlib/datatypes/heap.v:37:15: error: cannot use `>` as `<=` operator method is not defined - 35 | mut left := heap.left_child(parent) or { return item } - 36 | mut right := heap.right_child(parent) or { left } - 37 | for heap.data[parent] > heap.data[left] || heap.data[parent] > heap.data[right] { +vlib/datatypes/heap.v:44:15: error: cannot use `>` as `<=` operator method is not defined + 42 | mut left := heap.left_child(parent) or { return item } + 43 | mut right := heap.right_child(parent) or { left } + 44 | for heap.data[parent] > heap.data[left] || heap.data[parent] > heap.data[right] { | ~~~~~~~~~~~~~~~~~~~~~~~~~~ - 38 | // choose min for min heap - 39 | swap := if heap.data[left] <= heap.data[right] { left } else { right } -vlib/datatypes/heap.v:39:23: error: cannot use `<=` as `<` operator method is not defined - 37 | for heap.data[parent] > heap.data[left] || heap.data[parent] > heap.data[right] { - 38 | // choose min for min heap - 39 | swap := if heap.data[left] <= heap.data[right] { left } else { right } + 45 | // choose min for min heap + 46 | swap := if heap.data[left] <= heap.data[right] { left } else { right } +vlib/datatypes/heap.v:46:23: error: cannot use `<=` as `<` operator method is not defined + 44 | for heap.data[parent] > heap.data[left] || heap.data[parent] > heap.data[right] { + 45 | // choose min for min heap + 46 | swap := if heap.data[left] <= heap.data[right] { left } else { right } | ~~~~~~~~~~~~~~~~~~~~~~~~~~ - 40 | heap.data[parent], heap.data[swap] = heap.data[swap], heap.data[parent] - 41 | parent = swap + 47 | heap.data[parent], heap.data[swap] = heap.data[swap], heap.data[parent] + 48 | parent = swap