Skip to content

Commit 34f0d7a

Browse files
committed
Added Doubly Linked Lists example
1 parent 5733234 commit 34f0d7a

File tree

3 files changed

+292
-0
lines changed

3 files changed

+292
-0
lines changed

chap-03/doubly-linked-lists.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
/**
3+
* Created by PhpStorm.
4+
* User: bert
5+
* Date: 2/10/18
6+
* Time: 15:37
7+
*/
8+
9+
10+
use App\Chapter03\DoublyLinkedList;
11+
12+
require_once __DIR__ . '/../vendor/autoload.php';
13+
14+
define("SEPERATOR", PHP_EOL . "**********************************" . PHP_EOL);
15+
16+
$bookTitles = new DoublyLinkedList();
17+
18+
// Insert three books
19+
$bookTitles->insertAtFirst("Introduction to Algorithms");
20+
$bookTitles->insertAfter("Programming Intelligence", "Introduction to Algorithms");
21+
$bookTitles->insertAtLast("Handsome developers");
22+
$bookTitles->insertBefore("Student yearbook", "Programming Intelligence");
23+
24+
// Display data
25+
$bookTitles->displayForward();
26+
echo SEPERATOR;
27+
28+
// Display data backwards
29+
$bookTitles->displayBackward();
30+
echo SEPERATOR;

src/Chapter03/DoublyLinkedList.php

Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
<?php
2+
/**
3+
* Created by PhpStorm.
4+
* User: bert
5+
* Date: 3/10/18
6+
* Time: 9:46
7+
*/
8+
9+
namespace App\Chapter03;
10+
11+
12+
class DoublyLinkedList
13+
{
14+
private $_firstNode = NULL;
15+
private $_lastNode = NULL;
16+
private $_totalNodes = 0;
17+
18+
19+
/**
20+
* Inserts a new node at the first position of the doubly linked list.
21+
* We must check whether the list is empty (new node is both first and last) or not (mark new node as
22+
* beeing the first and assign previous first node as new node's next AND previous first node's previous to new node)
23+
* @param string|NULL $data
24+
* @return bool
25+
*/
26+
public function insertAtFirst(string $data = NULL)
27+
{
28+
$newNode = new DoublyListNode($data);
29+
30+
if ($this->_firstNode === NULL) {
31+
$this->_firstNode = &$newNode;
32+
$this->_lastNode = $newNode;
33+
} else {
34+
$currentFirstNode = $this->_firstNode;
35+
$this->_firstNode = &$newNode;
36+
$newNode->next = $currentFirstNode;
37+
$currentFirstNode->prev = $newNode;
38+
}
39+
$this->_totalNodes++;
40+
return true;
41+
}
42+
43+
/**
44+
* Inserts a new node at the last position of the doubly linked list.
45+
* We must check whether the list is empty (new node is both first and last) or not (mark new node as beeing the last
46+
* and set the previous and next properties accordingly.
47+
* @param string|NULL $data
48+
* @return bool
49+
*/
50+
public function insertAtLast(string $data = NULL)
51+
{
52+
$newNode = new DoublyListNode($data);
53+
54+
if ($this->_firstNode === NULL) {
55+
$this->_firstNode = &$newNode;
56+
$this->_lastNode = $newNode;
57+
} else {
58+
$currentNode = $this->_lastNode;
59+
$currentNode->next = $newNode;
60+
$newNode->prev = $currentNode;
61+
$this->_lastNode = $newNode;
62+
}
63+
$this->_totalNodes++;
64+
return true;
65+
}
66+
67+
/**
68+
* Inserts a new node before a specific node.
69+
* We need to find the node and based on its position, change the next and previous properties of the new node,
70+
* target node and the node before the target node.
71+
* @param string|NULL $data
72+
* @param string|NULL $query
73+
*/
74+
public function insertBefore(string $data = NULL, string $query = NULL)
75+
{
76+
$newNode = new DoublyListNode($data);
77+
if ($this->_firstNode) {
78+
$previous = NULL;
79+
$currentNode = $this->_firstNode;
80+
while ($currentNode !== NULL) {
81+
if ($currentNode->data === $query) {
82+
$newNode->next = $currentNode;
83+
$currentNode->prev = $newNode;
84+
$previous->next = $newNode;
85+
$newNode->prev = $previous;
86+
$this->_totalNodes++;
87+
break;
88+
}
89+
$previous = $currentNode;
90+
$currentNode = $currentNode->next;
91+
}
92+
}
93+
}
94+
95+
/**
96+
* Inserts a new node after a specific node.
97+
* We need to find the node and based on its position, change the next and prev properties of the new node, target
98+
* node and the node after the target node.
99+
* @param string|NULL $data
100+
* @param string|NULL $query
101+
*/
102+
public function insertAfter(string $data = NULL, string $query = NULL)
103+
{
104+
$newNode = new DoublyListNode($data);
105+
if ($this->_firstNode) {
106+
$nextNode = NULL;
107+
$currentNode = $this->_firstNode;
108+
while ($currentNode !== NULL) {
109+
if ($currentNode->data === $query) {
110+
111+
// Check if there is a node AFTER the found node
112+
if ($nextNode !== NULL) {
113+
$newNode->next = $nextNode;
114+
}
115+
// check if the found node is the last node.
116+
if ($currentNode === $this->_lastNode) {
117+
$this->_lastNode = $newNode;
118+
}
119+
120+
$currentNode->next = $newNode;
121+
$nextNode->prev = $newNode;
122+
$newNode->prev = $currentNode;
123+
124+
$this->_totalNodes++;
125+
break;
126+
}
127+
$currentNode = $currentNode->next;
128+
$nextNode = $currentNode;
129+
}
130+
}
131+
}
132+
133+
/**
134+
* Deletes the first node of the list.
135+
* We need to make the second node the first node after removing the item.
136+
* @return bool
137+
*/
138+
public function deleteFirst()
139+
{
140+
if ($this->_firstNode !== NULL) {
141+
// Check if this is the only item in the list and act accordingly.
142+
if ($this->_firstNode->next !== NULL) {
143+
$this->_firstNode = $this->_firstNode->next;
144+
$this->_firstNode->prev = NULL;
145+
} else {
146+
$this->_firstNode = NULL;
147+
}
148+
$this->_totalNodes--;
149+
return true;
150+
}
151+
return false;
152+
}
153+
154+
/**
155+
* Deletes the last node of the list.
156+
* We need to make the second to last node the last node after removing the item.
157+
* @return bool
158+
*/
159+
public function deleteLast()
160+
{
161+
if ($this->_lastNode !== NULL) {
162+
$currentNode = $this->_lastNode;
163+
// Check if this is the only item, delete first and last if so.
164+
if ($currentNode->prev === NULL) {
165+
$this->_firstNode = NULL;
166+
$this->_lastNode = NULL;
167+
} else {
168+
$previousNode = $currentNode->prev;
169+
$this->_lastNode = $previousNode;
170+
$previousNode->next = NULL;
171+
$this->_totalNodes--;
172+
return true;
173+
}
174+
}
175+
return false;
176+
}
177+
178+
/**
179+
* Deletes a given node from the list.
180+
* We need to make sure that always the previous and next nodes of the found node are tracked, and the next and prev
181+
* properties of both are set.
182+
* @param string|NULL $query
183+
*/
184+
public function delete(string $query = NULL)
185+
{
186+
if ($this->_firstNode) {
187+
$previous = NULL;
188+
$currentNode = $this->_firstNode;
189+
while ($currentNode !== NULL) {
190+
if ($currentNode->data === $query) {
191+
// Check if the found node is tha last one in the list.
192+
if ($currentNode->next === NULL) {
193+
$previous->next = NULL;
194+
} else {
195+
$previous->next = $currentNode->next;
196+
$currentNode->next->prev = $previous;
197+
}
198+
199+
$this->_totalNodes--;
200+
break;
201+
}
202+
$previous = $currentNode;
203+
$currentNode = $currentNode->next;
204+
}
205+
}
206+
}
207+
208+
/**
209+
* Displays the items in the list moving forward.
210+
* Starts from the first item.
211+
*/
212+
public function displayForward()
213+
{
214+
echo "Total book titles: " . $this->_totalNodes . PHP_EOL;
215+
$currentNode = $this->_firstNode;
216+
while ($currentNode !== NULL){
217+
echo $currentNode->data . PHP_EOL;
218+
$currentNode = $currentNode->next;
219+
}
220+
}
221+
222+
/**
223+
* Displays the items in the list moving backward.
224+
* Starts from the last item.
225+
*/
226+
public function displayBackward()
227+
{
228+
echo "Total book titles: " . $this->_totalNodes . PHP_EOL;
229+
$currentNode = $this->_lastNode;
230+
while ($currentNode !== NULL){
231+
echo $currentNode->data . PHP_EOL;
232+
$currentNode = $currentNode->prev;
233+
}
234+
}
235+
}

src/Chapter03/DoublyListNode.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
/**
3+
* Created by PhpStorm.
4+
* User: bert
5+
* Date: 3/10/18
6+
* Time: 9:45
7+
*/
8+
9+
namespace App\Chapter03;
10+
11+
12+
class DoublyListNode
13+
{
14+
public $data = NULL;
15+
public $next = NULL;
16+
public $prev = NULL;
17+
18+
/**
19+
* DoublyListNode constructor.
20+
*/
21+
public function __construct(string $data = NULL)
22+
{
23+
$this->data = $data;
24+
}
25+
26+
27+
}

0 commit comments

Comments
 (0)