Skip to content

Commit 07351e8

Browse files
authored
Merge pull request #2 from KaririCode-Framework/develop
Add LinkedList Implementation and Comprehensive Unit Tests
2 parents be67b80 + 88a6541 commit 07351e8

File tree

3 files changed

+447
-0
lines changed

3 files changed

+447
-0
lines changed

src/Collection/LinkedList.php

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace KaririCode\DataStructure\Collection;
6+
7+
use KaririCode\Contract\DataStructure\Structural\Collection;
8+
use KaririCode\DataStructure\Node;
9+
10+
/**
11+
* LinkedList implementation.
12+
*
13+
* This class implements a doubly-linked list, providing O(1) time complexity
14+
* for adding and removing elements at both ends, and O(n) for arbitrary index access.
15+
*
16+
* @category Collections
17+
*
18+
* @author Walmir Silva <walmir.silva@kariricode.org>
19+
* @license MIT
20+
*
21+
* @see https://kariricode.org/
22+
*/
23+
class LinkedList implements Collection
24+
{
25+
private ?Node $head = null;
26+
private ?Node $tail = null;
27+
private int $size = 0;
28+
29+
public function add(mixed $element): void
30+
{
31+
$newNode = new Node($element, $this->tail);
32+
if ($this->tail) {
33+
$this->tail->next = $newNode;
34+
} else {
35+
$this->head = $newNode;
36+
}
37+
$this->tail = $newNode;
38+
++$this->size;
39+
}
40+
41+
public function addAll(Collection $collection): void
42+
{
43+
foreach ($collection->getItems() as $element) {
44+
$this->add($element);
45+
}
46+
}
47+
48+
public function remove(mixed $element): bool
49+
{
50+
$current = $this->head;
51+
while (null !== $current) {
52+
if ($current->data === $element) {
53+
if ($current->prev) {
54+
$current->prev->next = $current->next;
55+
} else {
56+
$this->head = $current->next;
57+
}
58+
if ($current->next) {
59+
$current->next->prev = $current->prev;
60+
} else {
61+
$this->tail = $current->prev;
62+
}
63+
--$this->size;
64+
65+
return true;
66+
}
67+
$current = $current->next;
68+
}
69+
70+
return false;
71+
}
72+
73+
public function contains(mixed $element): bool
74+
{
75+
$current = $this->head;
76+
while (null !== $current) {
77+
if ($current->data === $element) {
78+
return true;
79+
}
80+
$current = $current->next;
81+
}
82+
83+
return false;
84+
}
85+
86+
public function clear(): void
87+
{
88+
$this->head = null;
89+
$this->tail = null;
90+
$this->size = 0;
91+
}
92+
93+
public function isEmpty(): bool
94+
{
95+
return 0 === $this->size;
96+
}
97+
98+
public function getItems(): array
99+
{
100+
$items = [];
101+
$current = $this->head;
102+
while (null !== $current) {
103+
$items[] = $current->data;
104+
$current = $current->next;
105+
}
106+
107+
return $items;
108+
}
109+
110+
public function count(): int
111+
{
112+
return $this->size;
113+
}
114+
115+
public function get(int $index): mixed
116+
{
117+
if ($index < 0 || $index >= $this->size) {
118+
throw new \OutOfRangeException("Index out of range: $index");
119+
}
120+
$current = $this->head;
121+
for ($i = 0; $i < $index; ++$i) {
122+
$current = $current->next;
123+
}
124+
125+
return $current->data;
126+
}
127+
128+
public function set(int $index, mixed $element): void
129+
{
130+
if ($index < 0 || $index >= $this->size) {
131+
throw new \OutOfRangeException("Index out of range: $index");
132+
}
133+
$current = $this->head;
134+
for ($i = 0; $i < $index; ++$i) {
135+
$current = $current->next;
136+
}
137+
$current->data = $element;
138+
}
139+
140+
/**
141+
* Clone method to ensure deep copy of nodes
142+
*/
143+
public function __clone()
144+
{
145+
$newList = new LinkedList();
146+
$current = $this->head;
147+
while ($current !== null) {
148+
$newList->add($current->data);
149+
$current = $current->next;
150+
}
151+
$this->head = $newList->head;
152+
$this->tail = $newList->tail;
153+
}
154+
}

src/Node.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace KaririCode\DataStructure;
6+
7+
class Node
8+
{
9+
public function __construct(
10+
public mixed $data,
11+
public ?Node $prev = null,
12+
public ?Node $next = null
13+
) {
14+
}
15+
}

0 commit comments

Comments
 (0)