Completed
Push — development ( 36da13...68c572 )
by Dylan David
01:48
created

DLNode   A

Complexity

Total Complexity 1

Size/Duplication

Total Lines 8
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 1
dl 0
loc 8
rs 10
c 0
b 0
f 0

1 Method

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
1
<?php
2
3
//TODO: Documentation, Unit Test
4
5
namespace Ptypes;
6
7
use Countable;
8
use Ptypes\Exceptions\InvalidArgument;
9
10
class DLNode //Doubly Linked Node
11
{
12
	public $next = null, $prev = null; //A reference to the next and previous node
13
	public $data = null; //Data or a reference to data
14
	
15
	public function __construct($data=null) 
16
	{
17
		$this->data = $data;
18
	}
19
}
20
21
class DoublyLinkedList implements Countable
22
{
23
	public $firstNode = null, $lastNode = null; //points to the first and last node of the list
24
	
25
	private $size = 0;
26
	
27
	public function __construct() {}
28
	
29
	public function insert_after($node, $newNode)
30
	{
31
		//type checks
32
		if (get_class($node) != "DLNode") {throw new InvalidArgument("Expected a DLNode, got: " . get_class($node)); }
33
		if (get_class($newNode) != "DLNode") {throw new InvalidArgument("Expected a DLNode, got: " . get_class($newNode)); }
34
		
35
		$newNode->prev = $node;
36
		if ($node->next == null)
37
		{
38
			$newNode->next = null;
39
			$this->lastNode = $newNode;
40
		}
41
		else
42
		{
43
			$newNode->next = $node->next;
44
			$node->next->prev = $newNode;
45
			$node->next = $newNode;
46
		}
47
		$this->size += 1;
48
	}
49
	
50
	public function insert_before($node, $newNode)
51
	{
52
		//type checks
53
		if (get_class($node) != "DLNode") {throw new InvalidArgument("Expected a DLNode, got: " . get_class($node)); }
54
		if (get_class($newNode) != "DLNode") {throw new InvalidArgument("Expected a DLNode, got: " . get_class($newNode)); }
55
		
56
		$newNode->next = $node;
57
		if ($node->prev == null)
58
		{
59
			$newNode->prev = null;
60
			$this->firstNode = $newNode;
61
		}
62
		else
63
		{
64
			$newNode->prev = $node->prev;
65
			$node->prev->next = $newNode;
66
			$node->prev = $newNode;
67
		}
68
		$this->size += 1;
69
	}
70
	
71
	public function insert_beginning($newNode)
72
	{	
73
		//type checks
74
		if (get_class($newNode) != "DLNode") {throw new InvalidArgument("Expected a DLNode, got: " . get_class($newNode)); }
75
		
76
		if ($this->firstNode == null)
77
		{
78
			$this->firstNode = $newNode;
79
			$this->lastNode = $newNode;
80
			$newNode->prev = null;
81
			$newNode->next = null;
82
		}
83
		else
84
		{
85
			$this->insert_before($this->firstNode, $newNode);
86
		}
87
		$this->size += 1;
88
	}
89
	
90
	public function insert_end($newNode)
91
	{
92
		if ($this->lastNode == null)
93
		{
94
			$this->insert_beginning($newNode);
95
		}
96
		else
97
		{
98
			$this->insert_after($this->lastNode, $newNode);
99
		}
100
		$this->size += 1;
101
	}
102
	
103
	public function contains($node)
104
	{
105
		//check this so we could possibly avoid list traversal
106
		if ($node == $this->firstNode || $node == $this->lastNode) {return true; }
107
		
108
		//traverse the list and try to find the node
109
		$n = $this->firstNode->next; //we can start one node ahead as we already checked the firstNode
110
		while ($n != null)
111
		{
112
			if ($n == $node) {return true; }
113
			$n = $n->next;
114
		}
115
		
116
		return false;
117
	}
118
	
119
	public function remove($node)
120
	{
121
		//check if the node exists
122
		if ($this->contains($node) == false) { throw new InvalidArgument("The node given does not exist in this list!"); }
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
123
		
124
		if ($node->prev == null)
125
		{
126
			$this->firstNode = $node->next;
127
		}
128
		else
129
		{
130
			$node->prev->next = $node->next;
131
		}
132
		
133
		if ($node->next == null)
134
		{
135
			$this->lastNode = $node->prev;
136
		}
137
		else
138
		{
139
			$node->next->prev = $node->prev;
140
		}
141
		$this->size -= 1;
142
	}
143
	
144
	public function get($index)
145
	{
146
		if($index < 0 || $index > $this->size-1)
147
		{
148
			throw new IndexOutOfBounds("The given index is out of bounds!");
0 ignored issues
show
Bug introduced by
The type Ptypes\IndexOutOfBounds was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
149
		}
150
		
151
		if($index == 0)
152
		{
153
			return $this->firstNode;
154
		}
155
		
156
		if($index == $this->size-1)
157
		{
158
			return $this->lastNode;
159
		}
160
		
161
		$node = $this->firstNode;
162
		for($i = 1; $i <= $index; $i++)
163
		{
164
			$node = $node->next;
165
		}
166
		
167
		return $node;
168
	}
169
	
170
	public function size()
171
	{
172
		return $this->size;
173
	}
174
	
175
	//Overriding functions & magic methods below
176
	
177
	/**
178
	 * Count, same functionality as Size.
179
	 * Overrides the default count function call on this class.
180
	 *
181
	 * @return int
182
	 */
183
	public function count()
184
	{
185
		return $this->size();
186
	}
187
}