Skip to content

Commit a6a15de

Browse files
authored
Merge pull request #8 from KaririCode-Framework/develop
Refactor and enhance data structures
2 parents 397d36b + 1d2a409 commit a6a15de

17 files changed

+689
-37
lines changed

composer.lock

Lines changed: 12 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Collection/ArrayList.php

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,25 +49,27 @@ public function remove(mixed $element): bool
4949

5050
public function contains(mixed $element): bool
5151
{
52-
return in_array($element, $this->elements, true);
52+
return null !== $this->find($element);
5353
}
5454

55-
public function clear(): void
55+
public function find(mixed $element): ?int
5656
{
57-
$this->elements = [];
58-
}
57+
$index = array_search($element, $this->elements, true);
5958

60-
public function isEmpty(): bool
61-
{
62-
return empty($this->elements);
59+
return false !== $index ? $index : null;
6360
}
6461

6562
public function getItems(): array
6663
{
6764
return $this->elements;
6865
}
6966

70-
public function count(): int
67+
public function clear(): void
68+
{
69+
$this->elements = [];
70+
}
71+
72+
public function size(): int
7173
{
7274
return count($this->elements);
7375
}

src/Collection/LinkedList.php

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,16 +71,21 @@ public function remove(mixed $element): bool
7171
}
7272

7373
public function contains(mixed $element): bool
74+
{
75+
return null !== $this->find($element);
76+
}
77+
78+
public function find(mixed $element): ?Node
7479
{
7580
$current = $this->head;
7681
while (null !== $current) {
7782
if ($current->data === $element) {
78-
return true;
83+
return $current;
7984
}
8085
$current = $current->next;
8186
}
8287

83-
return false;
88+
return null;
8489
}
8590

8691
public function clear(): void
@@ -107,7 +112,7 @@ public function getItems(): array
107112
return $items;
108113
}
109114

110-
public function count(): int
115+
public function size(): int
111116
{
112117
return $this->size;
113118
}

src/Map/HashMap.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace KaririCode\DataStructure\Map;
66

7+
use KaririCode\Contract\DataStructure\Behavioral\IterableCollection;
78
use KaririCode\Contract\DataStructure\Map;
89

910
/**
@@ -19,7 +20,7 @@
1920
*
2021
* @see https://kariricode.org/
2122
*/
22-
class HashMap implements Map
23+
class HashMap implements Map, IterableCollection, \IteratorAggregate
2324
{
2425
private array $map = [];
2526

@@ -68,4 +69,9 @@ public function values(): array
6869
{
6970
return array_values($this->map);
7071
}
72+
73+
public function getIterator(): \Iterator
74+
{
75+
return new \ArrayIterator($this->map);
76+
}
7177
}

src/Map/TreeMap.php

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace KaririCode\DataStructure\Map;
66

7+
use KaririCode\Contract\DataStructure\Behavioral\IterableCollection;
78
use KaririCode\Contract\DataStructure\Map;
89
use KaririCode\DataStructure\TreeMapNode;
910

@@ -20,16 +21,18 @@
2021
*
2122
* @see https://kariricode.org/
2223
*/
23-
class TreeMap implements Map
24+
class TreeMap implements Map, IterableCollection, \IteratorAggregate
2425
{
2526
private ?TreeMapNode $root = null;
27+
private int $size = 0;
2628

2729
public function put(mixed $key, mixed $value): void
2830
{
2931
$newNode = new TreeMapNode($key, $value);
3032
if (null === $this->root) {
3133
$this->root = $newNode;
3234
$this->root->setBlack();
35+
++$this->size;
3336
} else {
3437
$this->insertNode($newNode);
3538
$this->balanceAfterInsertion($newNode);
@@ -41,17 +44,90 @@ public function get(mixed $key): mixed
4144
return $this->findNode($key)?->value;
4245
}
4346

47+
public function keys(): array
48+
{
49+
$keys = [];
50+
$this->inOrderTraversalKeys($this->root, $keys);
51+
52+
return $keys;
53+
}
54+
55+
public function values(): array
56+
{
57+
$values = [];
58+
$this->inOrderTraversalValues($this->root, $values);
59+
60+
return $values;
61+
}
62+
4463
public function remove(mixed $key): bool
4564
{
4665
$node = $this->findNode($key);
4766
if (null === $node) {
4867
return false;
4968
}
5069
$this->deleteNode($node);
70+
--$this->size;
5171

5272
return true;
5373
}
5474

75+
public function size(): int
76+
{
77+
return $this->size;
78+
}
79+
80+
public function clear(): void
81+
{
82+
$this->root = null;
83+
$this->size = 0;
84+
}
85+
86+
public function containsKey(mixed $key): bool
87+
{
88+
return null !== $this->findNode($key);
89+
}
90+
91+
public function getItems(): array
92+
{
93+
$items = [];
94+
$this->inOrderTraversal($this->root, $items);
95+
96+
return $items;
97+
}
98+
99+
public function getIterator(): \Iterator
100+
{
101+
return new \ArrayIterator($this->getItems());
102+
}
103+
104+
private function inOrderTraversalKeys(?TreeMapNode $node, array &$keys): void
105+
{
106+
if (null !== $node) {
107+
$this->inOrderTraversalKeys($node->left, $keys);
108+
$keys[] = $node->key;
109+
$this->inOrderTraversalKeys($node->right, $keys);
110+
}
111+
}
112+
113+
private function inOrderTraversalValues(?TreeMapNode $node, array &$values): void
114+
{
115+
if (null !== $node) {
116+
$this->inOrderTraversalValues($node->left, $values);
117+
$values[] = $node->value;
118+
$this->inOrderTraversalValues($node->right, $values);
119+
}
120+
}
121+
122+
private function inOrderTraversal(?TreeMapNode $node, array &$items): void
123+
{
124+
if (null !== $node) {
125+
$this->inOrderTraversal($node->left, $items);
126+
$items[$node->key] = $node->value;
127+
$this->inOrderTraversal($node->right, $items);
128+
}
129+
}
130+
55131
private function insertNode(TreeMapNode $newNode): void
56132
{
57133
$current = $this->root;
@@ -76,6 +152,8 @@ private function insertNode(TreeMapNode $newNode): void
76152
} else {
77153
$parent->right = $newNode;
78154
}
155+
156+
++$this->size;
79157
$this->balanceAfterInsertion($newNode);
80158
}
81159

src/Queue/ArrayDeque.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
namespace KaririCode\DataStructure\Queue;
66

77
use KaririCode\Contract\DataStructure\Deque;
8-
use KaririCode\Contract\DataStructure\Queue;
98

109
/**
1110
* ArrayDeque implementation.
@@ -52,4 +51,9 @@ public function peekLast(): mixed
5251

5352
return $this->elements[$index];
5453
}
54+
55+
public function add(mixed $element): void
56+
{
57+
$this->addLast($element);
58+
}
5559
}

src/Queue/ArrayQueue.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,8 @@
2121
*/
2222
class ArrayQueue extends CircularArrayQueue implements Queue
2323
{
24-
// No additional methods required, uses methods from CircularArrayQueue
24+
public function add(mixed $element): void
25+
{
26+
$this->enqueue($element);
27+
}
2528
}

src/Queue/CircularArrayQueue.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,16 @@ public function enqueue(mixed $element): void
8888
++$this->size;
8989
}
9090

91+
public function addLast(mixed $element): void
92+
{
93+
$this->enqueue($element);
94+
}
95+
96+
public function removeFirst(): mixed
97+
{
98+
return $this->dequeue();
99+
}
100+
91101
public function getItems(): array
92102
{
93103
$items = [];
@@ -97,4 +107,23 @@ public function getItems(): array
97107

98108
return $items;
99109
}
110+
111+
public function remove(mixed $element): bool
112+
{
113+
for ($i = 0; $i < $this->size; ++$i) {
114+
$index = ($this->front + $i) % $this->capacity;
115+
if ($this->elements[$index] === $element) {
116+
// Shift elements to the left to fill the gap
117+
for ($j = $index; $j !== ($this->front + $this->size - 1) % $this->capacity; $j = ($j + 1) % $this->capacity) {
118+
$this->elements[$j] = $this->elements[($j + 1) % $this->capacity];
119+
}
120+
$this->elements[($this->front + $this->size - 1) % $this->capacity] = null;
121+
--$this->size;
122+
123+
return true;
124+
}
125+
}
126+
127+
return false;
128+
}
100129
}

0 commit comments

Comments
 (0)