Skip to content

Commit c922b60

Browse files
committed
chapter 05: [LinkedLists]
1 parent bacfd56 commit c922b60

File tree

3 files changed

+87
-152
lines changed

3 files changed

+87
-152
lines changed
+16-76
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
import { defaultEquals, IEqualsFunction } from '../util';
2+
import LinkedList from './linked-list';
23
import { Node } from './models/linked-list-models';
34

4-
export default class CircularLinkedList<T> {
5-
private count = 0;
6-
private head: Node<T> | undefined;
5+
export default class CircularLinkedList<T> extends LinkedList<T> {
76

8-
constructor(private equalsFn: IEqualsFunction<T> = defaultEquals) { }
7+
constructor(protected equalsFn: IEqualsFunction<T> = defaultEquals) {
8+
super(equalsFn);
9+
}
910

1011
private getLastElement() {
1112
let current = this.head;
12-
for (let i = 2; i <= this.size() && current; i++) {
13+
for (let i = 2; i <= this.size() && current != null; i++) {
1314
current = current.next;
1415
}
1516
return current;
@@ -19,11 +20,11 @@ export default class CircularLinkedList<T> {
1920
const node = new Node(element);
2021
let current;
2122

22-
if (this.head === undefined || this.head === null) {
23+
if (this.head == null) {
2324
this.head = node;
2425
} else {
2526
current = this.getLastElement();
26-
if (current) {
27+
if (current != null) {
2728
current.next = node;
2829
}
2930
}
@@ -34,26 +35,13 @@ export default class CircularLinkedList<T> {
3435
this.count++;
3536
}
3637

37-
getElementAt(index: number) {
38-
if (index >= 0 && index <= this.count) {
39-
let node = this.head;
40-
for (let i = 0; i < index; i++) {
41-
if (node) {
42-
node = node.next;
43-
}
44-
}
45-
return node;
46-
}
47-
return undefined;
48-
}
49-
5038
insert(index: number, element: T) {
5139
if (index >= 0 && index <= this.count) {
5240
const node = new Node(element);
5341
let current = this.head;
5442

5543
if (index === 0) {
56-
if (!this.head) {
44+
if (this.head == null) {
5745
// if no node in list
5846
this.head = node;
5947
node.next = this.head;
@@ -62,13 +50,13 @@ export default class CircularLinkedList<T> {
6250
current = this.getLastElement();
6351
// update last element
6452
this.head = node;
65-
if (current) {
53+
if (current != null) {
6654
current.next = this.head;
6755
}
6856
}
6957
} else {
7058
const previous = this.getElementAt(index - 1);
71-
if (previous) {
59+
if (previous != null) {
7260
node.next = previous.next;
7361
previous.next = node;
7462
}
@@ -90,77 +78,29 @@ export default class CircularLinkedList<T> {
9078
this.head = undefined;
9179
} else {
9280
current = this.getLastElement();
93-
if (this.head) {
81+
if (this.head != null) {
9482
this.head = this.head.next;
9583
}
96-
if (current) {
84+
if (current != null) {
9785
current.next = this.head;
9886
}
9987
current = removed;
10088
}
10189
} else {
10290
// no need to update last element for circular list
10391
const previous = this.getElementAt(index - 1);
104-
if (previous) {
92+
if (previous != null) {
10593
current = previous.next;
106-
if (current) {
94+
if (current != null) {
10795
previous.next = current.next;
10896
}
10997
}
11098
}
111-
if (current) {
99+
if (current != null) {
112100
this.count--;
113101
return current.element;
114102
}
115103
}
116104
return undefined;
117105
}
118-
119-
remove(element: T) {
120-
const index = this.indexOf(element);
121-
return this.removeAt(index);
122-
}
123-
124-
indexOf(element: T) {
125-
let current = this.head;
126-
127-
for (let i = 1; i <= this.size() && current; i++) {
128-
if (this.equalsFn(element, current.element)) {
129-
return i - 1;
130-
}
131-
current = current.next;
132-
}
133-
134-
return -1;
135-
}
136-
137-
isEmpty() {
138-
return this.size() === 0;
139-
}
140-
141-
size() {
142-
return this.count;
143-
}
144-
145-
getHead() {
146-
return this.head;
147-
}
148-
149-
clear() {
150-
this.head = undefined;
151-
this.count = 0;
152-
}
153-
154-
toString() {
155-
if (this.head === undefined) {
156-
return '';
157-
}
158-
let objString = `${this.head.element}`;
159-
let current = this.head.next;
160-
for (let i = 2; i <= this.size() && current; i++) {
161-
objString = `${objString},${current.element}`;
162-
current = current.next;
163-
}
164-
return objString;
165-
}
166106
}

src/ts/data-structures/doubly-linked-list.ts

+28-57
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,24 @@
11
import { defaultEquals, IEqualsFunction } from '../util';
2+
import LinkedList from './linked-list';
23
import { DoublyNode } from './models/linked-list-models';
34

4-
export default class DoublyLinkedList<T> {
5-
private count = 0;
6-
private head: DoublyNode<T> | undefined;
7-
private tail: DoublyNode<T> | undefined;
5+
export default class DoublyLinkedList<T> extends LinkedList<T> {
6+
protected head: DoublyNode<T> | undefined;
7+
protected tail: DoublyNode<T> | undefined;
88

9-
constructor(private equalsFn: IEqualsFunction<T> = defaultEquals) { }
9+
constructor(protected equalsFn: IEqualsFunction<T> = defaultEquals) {
10+
super(equalsFn);
11+
}
1012

1113
push(element: T) {
1214
const node = new DoublyNode(element);
1315

14-
if (this.head === undefined || this.head === null) {
16+
if (this.head == null) {
1517
this.head = node;
1618
this.tail = node; // NEW
1719
} else {
1820
// attach to the tail node // NEW
19-
if (this.tail !== undefined && this.tail !== null) {
21+
if (this.tail != null) {
2022
this.tail.next = node;
2123
node.prev = this.tail;
2224
this.tail = node;
@@ -25,26 +27,13 @@ export default class DoublyLinkedList<T> {
2527
this.count++;
2628
}
2729

28-
getElementAt(index: number) {
29-
if (index >= 0 && index <= this.count) {
30-
let node = this.head;
31-
for (let i = 0; i < index; i++) {
32-
if (node) {
33-
node = node.next;
34-
}
35-
}
36-
return node;
37-
}
38-
return undefined;
39-
}
40-
4130
insert(index: number, element: T) {
4231
if (index >= 0 && index <= this.count) {
4332
const node = new DoublyNode(element);
4433
let current = this.head;
4534

4635
if (index === 0) {
47-
if (this.head === undefined || this.head === null) {
36+
if (this.head == null) {
4837
// NEW
4938
this.head = node;
5039
this.tail = node;
@@ -57,19 +46,19 @@ export default class DoublyLinkedList<T> {
5746
// last item // NEW
5847

5948
current = this.tail; // {2}
60-
if (current) {
49+
if (current != null) {
6150
current.next = node;
6251
node.prev = current;
6352
this.tail = node;
6453
}
6554
} else {
6655
const previous = this.getElementAt(index - 1);
67-
if (previous) {
56+
if (previous != null) {
6857
current = previous.next;
6958
node.next = current;
7059
previous.next = node;
7160

72-
if (current) {
61+
if (current != null) {
7362
current.prev = node; // NEW
7463
node.prev = previous; // NEW
7564
}
@@ -86,58 +75,53 @@ export default class DoublyLinkedList<T> {
8675
let current = this.head;
8776

8877
if (index === 0) {
89-
if (this.head) {
78+
if (this.head != null) {
9079
this.head = this.head.next; // {1}
9180
// if there is only one item, then we update tail as well //NEW
9281
if (this.count === 1) {
9382
// {2}
9483
this.tail = undefined;
9584
} else {
96-
if (this.head) {
85+
if (this.head != null) {
9786
this.head.prev = undefined; // {3}
9887
}
9988
}
10089
}
10190
} else if (index === this.count - 1) {
10291
// last item //NEW
10392
current = this.tail; // {4}
104-
if (current) {
93+
if (current != null) {
10594
this.tail = current.prev;
10695
if (this.tail) {
10796
this.tail.next = undefined;
10897
}
10998
}
11099
} else {
111100
current = this.getElementAt(index);
112-
if (current) {
101+
if (current != null) {
113102
const previous = current.prev;
114-
if (previous) {
103+
if (previous != null) {
115104
// link previous with current's next - skip it to remove
116105
previous.next = current.next; // {6}
117-
if (current && current.next) {
106+
if (current != null && current.next != null) {
118107
current.next.prev = previous; // NEW
119108
}
120109
}
121110
}
122111
}
123-
if (current) {
112+
if (current != null) {
124113
this.count--;
125114
return current.element;
126115
}
127116
}
128117
return undefined;
129118
}
130119

131-
remove(element: T) {
132-
const index = this.indexOf(element);
133-
return this.removeAt(index);
134-
}
135-
136120
indexOf(element: T) {
137121
let current = this.head;
138122
let index = 0;
139123

140-
while (current) {
124+
while (current != null) {
141125
if (this.equalsFn(element, current.element)) {
142126
return index;
143127
}
@@ -148,48 +132,35 @@ export default class DoublyLinkedList<T> {
148132
return -1;
149133
}
150134

151-
getHead() {
152-
return this.head;
153-
}
154-
155135
getTail() {
156136
return this.tail;
157137
}
158138

159-
isEmpty() {
160-
return this.size() === 0;
161-
}
162-
163139
clear() {
164-
this.head = undefined;
140+
super.clear();
165141
this.tail = undefined;
166-
this.count = 0;
167-
}
168-
169-
size() {
170-
return this.count;
171142
}
172143

173144
toString() {
174-
if (this.head === undefined) {
145+
if (this.head == null) {
175146
return '';
176147
}
177148
let objString = `${this.head.element}`;
178-
let current: DoublyNode<T> | undefined = this.head.next;
179-
while (current) {
149+
let current = this.head.next;
150+
while (current != null) {
180151
objString = `${objString},${current.element}`;
181152
current = current.next;
182153
}
183154
return objString;
184155
}
185156

186157
inverseToString() {
187-
if (this.tail === undefined) {
158+
if (this.tail == null) {
188159
return '';
189160
}
190161
let objString = `${this.tail.element}`;
191-
let previous: DoublyNode<T> | undefined = this.tail.prev;
192-
while (previous) {
162+
let previous = this.tail.prev;
163+
while (previous != null) {
193164
objString = `${objString},${previous.element}`;
194165
previous = previous.prev;
195166
}

0 commit comments

Comments
 (0)