Skip to content

Commit 17cfa43

Browse files
committedOct 15, 2017
chapter 05: [LinkedLists]
1 parent 1a4f18e commit 17cfa43

File tree

10 files changed

+477
-169
lines changed

10 files changed

+477
-169
lines changed
 

‎src/ts/data-structures/circular-linked-list.ts

Lines changed: 11 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import LinkedList from './linked-list';
33
import { Node } from './models/linked-list-models';
44

55
export default class CircularLinkedList<T> extends LinkedList<T> {
6-
76
constructor(protected equalsFn: IEqualsFunction<T> = defaultEquals) {
87
super(equalsFn);
98
}
@@ -24,9 +23,7 @@ export default class CircularLinkedList<T> extends LinkedList<T> {
2423
this.head = node;
2524
} else {
2625
current = this.getLastElement();
27-
if (current != null) {
28-
current.next = node;
29-
}
26+
current.next = node;
3027
}
3128

3229
// set node.next to head - to have circular list
@@ -35,7 +32,7 @@ export default class CircularLinkedList<T> extends LinkedList<T> {
3532
this.count++;
3633
}
3734

38-
insert(index: number, element: T) {
35+
insert(element: T, index: number) {
3936
if (index >= 0 && index <= this.count) {
4037
const node = new Node(element);
4138
let current = this.head;
@@ -50,16 +47,12 @@ export default class CircularLinkedList<T> extends LinkedList<T> {
5047
current = this.getLastElement();
5148
// update last element
5249
this.head = node;
53-
if (current != null) {
54-
current.next = this.head;
55-
}
50+
current.next = this.head;
5651
}
5752
} else {
5853
const previous = this.getElementAt(index - 1);
59-
if (previous != null) {
60-
node.next = previous.next;
61-
previous.next = node;
62-
}
54+
node.next = previous.next;
55+
previous.next = node;
6356
}
6457
this.count++;
6558
return true;
@@ -78,28 +71,18 @@ export default class CircularLinkedList<T> extends LinkedList<T> {
7871
this.head = undefined;
7972
} else {
8073
current = this.getLastElement();
81-
if (this.head != null) {
82-
this.head = this.head.next;
83-
}
84-
if (current != null) {
85-
current.next = this.head;
86-
}
74+
this.head = this.head.next;
75+
current.next = this.head;
8776
current = removed;
8877
}
8978
} else {
9079
// no need to update last element for circular list
9180
const previous = this.getElementAt(index - 1);
92-
if (previous != null) {
93-
current = previous.next;
94-
if (current != null) {
95-
previous.next = current.next;
96-
}
97-
}
98-
}
99-
if (current != null) {
100-
this.count--;
101-
return current.element;
81+
current = previous.next;
82+
previous.next = current.next;
10283
}
84+
this.count--;
85+
return current.element;
10386
}
10487
return undefined;
10588
}

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

Lines changed: 28 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,14 @@ export default class DoublyLinkedList<T> extends LinkedList<T> {
1818
this.tail = node; // NEW
1919
} else {
2020
// attach to the tail node // NEW
21-
if (this.tail != null) {
22-
this.tail.next = node;
23-
node.prev = this.tail;
24-
this.tail = node;
25-
}
21+
this.tail.next = node;
22+
node.prev = this.tail;
23+
this.tail = node;
2624
}
2725
this.count++;
2826
}
2927

30-
insert(index: number, element: T) {
28+
insert(element: T, index: number) {
3129
if (index >= 0 && index <= this.count) {
3230
const node = new DoublyNode(element);
3331
let current = this.head;
@@ -46,23 +44,17 @@ export default class DoublyLinkedList<T> extends LinkedList<T> {
4644
// last item // NEW
4745

4846
current = this.tail; // {2}
49-
if (current != null) {
50-
current.next = node;
51-
node.prev = current;
52-
this.tail = node;
53-
}
47+
current.next = node;
48+
node.prev = current;
49+
this.tail = node;
5450
} else {
5551
const previous = this.getElementAt(index - 1);
56-
if (previous != null) {
57-
current = previous.next;
58-
node.next = current;
59-
previous.next = node;
60-
61-
if (current != null) {
62-
current.prev = node; // NEW
63-
node.prev = previous; // NEW
64-
}
65-
}
52+
current = previous.next;
53+
node.next = current;
54+
previous.next = node;
55+
56+
current.prev = node; // NEW
57+
node.prev = previous; // NEW
6658
}
6759
this.count++;
6860
return true;
@@ -75,44 +67,28 @@ export default class DoublyLinkedList<T> extends LinkedList<T> {
7567
let current = this.head;
7668

7769
if (index === 0) {
78-
if (this.head != null) {
79-
this.head = this.head.next; // {1}
80-
// if there is only one item, then we update tail as well //NEW
81-
if (this.count === 1) {
82-
// {2}
83-
this.tail = undefined;
84-
} else {
85-
if (this.head != null) {
86-
this.head.prev = undefined; // {3}
87-
}
88-
}
70+
this.head = this.head.next; // {1}
71+
// if there is only one item, then we update tail as well //NEW
72+
if (this.count === 1) {
73+
// {2}
74+
this.tail = undefined;
75+
} else {
76+
this.head.prev = undefined; // {3}
8977
}
9078
} else if (index === this.count - 1) {
9179
// last item //NEW
9280
current = this.tail; // {4}
93-
if (current != null) {
94-
this.tail = current.prev;
95-
if (this.tail) {
96-
this.tail.next = undefined;
97-
}
98-
}
81+
this.tail = current.prev;
82+
this.tail.next = undefined;
9983
} else {
10084
current = this.getElementAt(index);
101-
if (current != null) {
102-
const previous = current.prev;
103-
if (previous != null) {
104-
// link previous with current's next - skip it to remove
105-
previous.next = current.next; // {6}
106-
if (current != null && current.next != null) {
107-
current.next.prev = previous; // NEW
108-
}
109-
}
110-
}
111-
}
112-
if (current != null) {
113-
this.count--;
114-
return current.element;
85+
const previous = current.prev;
86+
// link previous with current's next - skip it to remove
87+
previous.next = current.next; // {6}
88+
current.next.prev = previous; // NEW
11589
}
90+
this.count--;
91+
return current.element;
11692
}
11793
return undefined;
11894
}

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

Lines changed: 14 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,18 @@
1-
import { defaultCompare, defaultEquals, ICompareFunction, IEqualsFunction } from '../util';
1+
import { defaultEquals, IEqualsFunction } from '../util';
22
import { Node } from './models/linked-list-models';
33

44
export default class LinkedList<T> {
55
protected count = 0;
66
protected head: Node<T> | undefined;
77

8-
constructor(
9-
protected equalsFn: IEqualsFunction<T> = defaultEquals,
10-
protected compareFn: ICompareFunction<T> = defaultCompare
11-
) {}
8+
constructor(protected equalsFn: IEqualsFunction<T> = defaultEquals) {}
129

1310
push(element: T) {
1411
const node = new Node(element);
1512
let current;
1613

17-
if (this.head == null) { // catches null && undefined
14+
if (this.head == null) {
15+
// catches null && undefined
1816
this.head = node;
1917
} else {
2018
current = this.head;
@@ -31,17 +29,15 @@ export default class LinkedList<T> {
3129
getElementAt(index: number) {
3230
if (index >= 0 && index <= this.count) {
3331
let node = this.head;
34-
for (let i = 0; i < index; i++) {
35-
if (node != null) {
36-
node = node.next;
37-
}
32+
for (let i = 0; i < index && node != null; i++) {
33+
node = node.next;
3834
}
3935
return node;
4036
}
4137
return undefined;
4238
}
4339

44-
insert(index: number, element: T) {
40+
insert(element: T, index: number) {
4541
if (index >= 0 && index <= this.count) {
4642
const node = new Node(element);
4743
const current = this.head;
@@ -51,61 +47,28 @@ export default class LinkedList<T> {
5147
this.head = node;
5248
} else {
5349
const previous = this.getElementAt(index - 1);
54-
if (previous != null) {
55-
node.next = previous.next;
56-
previous.next = node;
57-
}
50+
node.next = previous.next;
51+
previous.next = node;
5852
}
5953
this.count++;
6054
return true;
6155
}
6256
return false;
6357
}
6458

65-
insertSorted(element: T) {
66-
if (this.isEmpty()) {
67-
this.push(element);
68-
} else {
69-
const index = this.getIndexNextSortedElement(element);
70-
this.insert(index, element);
71-
}
72-
}
73-
74-
private getIndexNextSortedElement(element: T) {
75-
let current = this.head;
76-
77-
for (let i = 0; i < this.size() && current; i++) {
78-
const comp = this.compareFn(element, current.element);
79-
if (comp >= 0) {
80-
return i;
81-
}
82-
current = current.next;
83-
}
84-
85-
return -1;
86-
}
87-
8859
removeAt(index: number) {
8960
if (index >= 0 && index < this.count) {
9061
let current = this.head;
9162

9263
if (index === 0) {
93-
if (this.head != null) {
94-
this.head = this.head.next;
95-
}
64+
this.head = current.next;
9665
} else {
9766
const previous = this.getElementAt(index - 1);
98-
if (previous != null) {
99-
current = previous.next;
100-
if (current != null) {
101-
previous.next = current.next;
102-
}
103-
}
104-
}
105-
if (current != null) {
106-
this.count--;
107-
return current.element;
67+
current = previous.next;
68+
previous.next = current.next;
10869
}
70+
this.count--;
71+
return current.element;
10972
}
11073
return undefined;
11174
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { Compare, defaultCompare, defaultEquals, ICompareFunction, IEqualsFunction } from '../util';
2+
import LinkedList from './linked-list';
3+
4+
export default class SortedLinkedList<T> extends LinkedList<T> {
5+
constructor(
6+
protected equalsFn: IEqualsFunction<T> = defaultEquals,
7+
protected compareFn: ICompareFunction<T> = defaultCompare
8+
) {
9+
super(equalsFn);
10+
}
11+
12+
push(element: T) {
13+
if (this.isEmpty()) {
14+
super.push(element);
15+
} else {
16+
const index = this.getIndexNextSortedElement(element);
17+
super.insert(element, index);
18+
}
19+
}
20+
21+
insert(element: T, index: number = 0) {
22+
if (this.isEmpty()) {
23+
return super.insert(element, 0);
24+
}
25+
index = this.getIndexNextSortedElement(element);
26+
return super.insert(element, index);
27+
}
28+
29+
private getIndexNextSortedElement(element: T) {
30+
let current = this.head;
31+
let i = 0;
32+
33+
for (; i < this.size() && current; i++) {
34+
const comp = this.compareFn(element, current.element);
35+
if (comp === Compare.LESS_THAN) {
36+
return i;
37+
}
38+
current = current.next;
39+
}
40+
41+
return i;
42+
}
43+
}

‎src/ts/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
import * as _util from './util';
2+
13
export { default as CircularLinkedList } from './data-structures/circular-linked-list';
24
export { default as DoublyLinkedList } from './data-structures/doubly-linked-list';
35
export { default as LinkedList } from './data-structures/linked-list';
6+
export { default as SortedLinkedList } from './data-structures/sorted-linked-list';
47

5-
import * as _util from './util';
68
export const util = _util;
79

810
/* import { hotPotato } from './others/hot-potato';

‎test/ts/data-structures/circular-linked-list.spec.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -80,15 +80,15 @@ describe('CircularLinkedList', () => {
8080
it('inserts elements first position empty list', () => {
8181
const element = 1;
8282
max = element;
83-
expect(list.insert(0, element)).to.equal(true);
83+
expect(list.insert(element, 0)).to.equal(true);
8484
verifyList();
8585
});
8686

8787
it('inserts elements first position not empty list', () => {
8888
max = 2;
89-
expect(list.insert(0, max)).to.equal(true);
89+
expect(list.insert(max, 0)).to.equal(true);
9090

91-
expect(list.insert(0, min)).to.equal(true);
91+
expect(list.insert(min, 0)).to.equal(true);
9292

9393
verifyList();
9494
});
@@ -99,22 +99,22 @@ describe('CircularLinkedList', () => {
9999

100100
it('inserts elements invalid position not empty list', () => {
101101
const element = 1;
102-
expect(list.insert(0, element)).to.equal(true);
103-
expect(list.insert(2, element)).to.equal(false);
102+
expect(list.insert(element, 0)).to.equal(true);
103+
expect(list.insert(element, 2)).to.equal(false);
104104
});
105105

106106
it('inserts elements in the middle of list', () => {
107-
expect(list.insert(0, 3)).to.equal(true);
108-
expect(list.insert(0, 1)).to.equal(true);
109-
expect(list.insert(1, 2)).to.equal(true);
107+
expect(list.insert(3, 0)).to.equal(true);
108+
expect(list.insert(1, 0)).to.equal(true);
109+
expect(list.insert(2, 1)).to.equal(true);
110110
verifyList();
111111
});
112112

113113
it('inserts elements at the end of list', () => {
114114
max = 5;
115115

116116
for (let i = min; i <= max; i++) {
117-
expect(list.insert(i - 1, i)).to.equal(true);
117+
expect(list.insert(i , i - 1)).to.equal(true);
118118
}
119119

120120
verifyList();
@@ -243,7 +243,7 @@ describe('CircularLinkedList', () => {
243243
pushesElements();
244244

245245
const maxIndex = max;
246-
for (let i = max; i >= min; i--) {
246+
for (let i = maxIndex; i >= min; i--) {
247247
element = list.removeAt(i - 1);
248248
expect(element).to.not.be.an('undefined');
249249
expect(element).to.equal(i);

‎test/ts/data-structures/doubly-linked-list.spec.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -105,15 +105,15 @@ describe('DoublyLinkedList', () => {
105105
it('inserts elements first position empty list', () => {
106106
const element = 1;
107107
max = element;
108-
expect(list.insert(0, element)).to.equal(true);
108+
expect(list.insert(element, 0)).to.equal(true);
109109
verifyList();
110110
});
111111

112112
it('inserts elements first position not empty list', () => {
113113
max = 2;
114-
expect(list.insert(0, max)).to.equal(true);
114+
expect(list.insert(max, 0)).to.equal(true);
115115

116-
expect(list.insert(0, min)).to.equal(true);
116+
expect(list.insert(min, 0)).to.equal(true);
117117

118118
verifyList();
119119
});
@@ -124,24 +124,24 @@ describe('DoublyLinkedList', () => {
124124

125125
it('inserts elements invalid position not empty list', () => {
126126
const element = 1;
127-
expect(list.insert(0, element)).to.equal(true);
128-
expect(list.insert(2, element)).to.equal(false);
127+
expect(list.insert(element, 0)).to.equal(true);
128+
expect(list.insert(element, 2)).to.equal(false);
129129
});
130130

131131
it('inserts elements at the end of list', () => {
132132
max = 5;
133133

134134
for (let i = min; i <= max; i++) {
135-
expect(list.insert(i - 1, i)).to.equal(true);
135+
expect(list.insert(i , i - 1)).to.equal(true);
136136
}
137137

138138
verifyList();
139139
});
140140

141141
it('inserts elements in the middle of list', () => {
142-
expect(list.insert(0, 3)).to.equal(true);
143-
expect(list.insert(0, 1)).to.equal(true);
144-
expect(list.insert(1, 2)).to.equal(true);
142+
expect(list.insert(3, 0)).to.equal(true);
143+
expect(list.insert(1, 0)).to.equal(true);
144+
expect(list.insert(2, 1)).to.equal(true);
145145
verifyList();
146146
});
147147

@@ -231,7 +231,7 @@ describe('DoublyLinkedList', () => {
231231
pushesElements();
232232

233233
const maxIndex = max;
234-
for (let i = max; i >= min; i--) {
234+
for (let i = maxIndex; i >= min; i--) {
235235
element = list.removeAt(i - 1);
236236
expect(element).to.not.be.an('undefined');
237237
expect(element).to.equal(i);

‎test/ts/data-structures/linked-list.spec.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -75,15 +75,15 @@ describe('LinkedList', () => {
7575
it('inserts elements first position empty list', () => {
7676
const element = 1;
7777
max = element;
78-
expect(list.insert(0, element)).to.equal(true);
78+
expect(list.insert(element, 0)).to.equal(true);
7979
verifyList();
8080
});
8181

8282
it('inserts elements first position not empty list', () => {
8383
max = 2;
84-
expect(list.insert(0, max)).to.equal(true);
84+
expect(list.insert(max, 0)).to.equal(true);
8585

86-
expect(list.insert(0, min)).to.equal(true);
86+
expect(list.insert(min, 0)).to.equal(true);
8787

8888
verifyList();
8989
});
@@ -94,22 +94,22 @@ describe('LinkedList', () => {
9494

9595
it('inserts elements invalid position not empty list', () => {
9696
const element = 1;
97-
expect(list.insert(0, element)).to.equal(true);
98-
expect(list.insert(2, element)).to.equal(false);
97+
expect(list.insert(element, 0)).to.equal(true);
98+
expect(list.insert(element, 2)).to.equal(false);
9999
});
100100

101101
it('inserts elements in the middle of list', () => {
102-
expect(list.insert(0, 3)).to.equal(true);
103-
expect(list.insert(0, 1)).to.equal(true);
104-
expect(list.insert(1, 2)).to.equal(true);
102+
expect(list.insert(3, 0)).to.equal(true);
103+
expect(list.insert(1, 0)).to.equal(true);
104+
expect(list.insert(2, 1)).to.equal(true);
105105
verifyList();
106106
});
107107

108108
it('inserts elements at the end of list', () => {
109109
max = 5;
110110

111111
for (let i = min; i <= max; i++) {
112-
expect(list.insert(i - 1, i)).to.equal(true);
112+
expect(list.insert(i , i - 1)).to.equal(true);
113113
}
114114

115115
verifyList();
@@ -231,7 +231,7 @@ describe('LinkedList', () => {
231231
pushesElements();
232232

233233
const maxIndex = max;
234-
for (let i = max; i >= min; i--) {
234+
for (let i = maxIndex; i >= min; i--) {
235235
element = list.removeAt(i - 1);
236236
expect(element).to.not.be.an('undefined');
237237
expect(element).to.equal(i);
Lines changed: 341 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,341 @@
1+
import 'mocha';
2+
import { expect } from 'chai';
3+
import { SortedLinkedList, util } from '../../../src/ts/index';
4+
import MyObj from './my-obj';
5+
6+
describe('SortedLinkedList', () => {
7+
let list: SortedLinkedList<number>;
8+
let min: number;
9+
let max: number;
10+
11+
beforeEach(function() {
12+
list = new SortedLinkedList<number>();
13+
min = 1;
14+
max = 3;
15+
});
16+
17+
function pushesElements() {
18+
for (let i = max; i >= min; i--) {
19+
list.push(i);
20+
}
21+
}
22+
23+
function verifyList() {
24+
let current = list.getHead();
25+
for (let i = min; i <= max && current; i++) {
26+
expect(current).to.not.be.an('undefined');
27+
if (current) {
28+
// TS strictNullChecks
29+
expect(current.element).to.not.be.an('undefined');
30+
expect(current.element).to.equal(i);
31+
if (i < max) {
32+
expect(current.next).to.not.be.an('undefined');
33+
if (current.next) {
34+
// TS strictNullChecks
35+
expect(current.next.element).to.equal(i + 1);
36+
}
37+
} else {
38+
expect(current.next).to.be.an('undefined');
39+
}
40+
current = current.next;
41+
}
42+
}
43+
}
44+
45+
it('starts empty', () => {
46+
expect(list.size()).to.equal(0);
47+
expect(list.isEmpty()).to.equal(true);
48+
expect(list.getHead()).to.be.an('undefined');
49+
});
50+
51+
it('pushes elements', () => {
52+
pushesElements();
53+
verifyList();
54+
});
55+
56+
it('returns element at specific index: invalid position', () => {
57+
// list is empty
58+
expect(list.getElementAt(3)).to.be.an('undefined');
59+
});
60+
61+
it('returns element at specific index', () => {
62+
let node;
63+
64+
pushesElements();
65+
66+
for (let i = min; i <= max; i++) {
67+
node = list.getElementAt(i - 1);
68+
expect(node).to.not.be.an('undefined');
69+
if (node) {
70+
expect(node.element).to.equal(i);
71+
}
72+
}
73+
});
74+
75+
it('inserts elements first position empty list', () => {
76+
const element = 1;
77+
max = element;
78+
expect(list.insert(element, 0)).to.equal(true);
79+
verifyList();
80+
});
81+
82+
it('inserts elements first position not empty list', () => {
83+
max = 2;
84+
expect(list.insert(max)).to.equal(true);
85+
86+
expect(list.insert(min, 0)).to.equal(true);
87+
88+
verifyList();
89+
});
90+
91+
it('inserts elements invalid position empty list', () => {
92+
// sorted list will ignore the index position
93+
expect(list.insert(1, 1)).to.equal(true);
94+
});
95+
96+
it('inserts elements invalid position not empty list', () => {
97+
// sorted list will ignore the index position
98+
const element = 1;
99+
expect(list.insert(element, 0)).to.equal(true);
100+
expect(list.insert(element, 2)).to.equal(true);
101+
});
102+
103+
it('inserts elements in the middle of list', () => {
104+
expect(list.insert(3, 0)).to.equal(true);
105+
expect(list.insert(1, 0)).to.equal(true);
106+
expect(list.insert(2, 1)).to.equal(true);
107+
verifyList();
108+
});
109+
110+
it('inserts elements at the end of list', () => {
111+
max = 5;
112+
113+
for (let i = min; i <= max; i++) {
114+
expect(list.insert(i , i - 1)).to.equal(true);
115+
}
116+
117+
verifyList();
118+
});
119+
120+
it('returns index of elements', () => {
121+
let index;
122+
123+
pushesElements();
124+
125+
for (let i = min; i <= max; i++) {
126+
index = list.indexOf(i);
127+
expect(index).to.equal(i - 1);
128+
}
129+
130+
expect(list.indexOf(max + 2)).to.equal(-1);
131+
});
132+
133+
it('removes valid elements', () => {
134+
let element;
135+
136+
pushesElements();
137+
138+
for (let i = min; i <= max; i++) {
139+
element = list.remove(i);
140+
expect(element).to.not.be.an('undefined');
141+
expect(element).to.equal(i);
142+
}
143+
});
144+
145+
it('removes invalid elements', () => {
146+
let element;
147+
148+
pushesElements();
149+
150+
for (let i = max + 2; i <= max + 4; i++) {
151+
element = list.remove(i);
152+
expect(element).to.be.an('undefined');
153+
}
154+
});
155+
156+
it('removes element invalid position empty list', () => {
157+
let element;
158+
159+
for (let i = min; i <= max; i++) {
160+
element = list.removeAt(i - 1);
161+
expect(element).to.be.an('undefined');
162+
}
163+
});
164+
165+
it('removes element invalid position not empty list', () => {
166+
let element;
167+
168+
pushesElements();
169+
170+
for (let i = max + 2; i <= max + 4; i++) {
171+
element = list.removeAt(i);
172+
expect(element).to.be.an('undefined');
173+
}
174+
});
175+
176+
it('removes first element list single element', () => {
177+
const value = 1;
178+
list.push(value);
179+
180+
const element = list.removeAt(0);
181+
expect(element).to.not.be.an('undefined');
182+
expect(element).to.equal(value);
183+
184+
expect(list.getHead()).to.be.an('undefined');
185+
expect(list.isEmpty()).to.equal(true);
186+
});
187+
188+
it('removes first element list multiple elements', () => {
189+
pushesElements();
190+
191+
const element = list.removeAt(0);
192+
expect(element).to.not.be.an('undefined');
193+
expect(element).to.equal(min);
194+
195+
min = 2;
196+
verifyList();
197+
});
198+
199+
it('removes element from middle of list', () => {
200+
pushesElements(); // 1, 2, 3
201+
202+
const element = list.removeAt(1); // element 2
203+
expect(element).to.not.be.an('undefined');
204+
expect(element).to.equal(2);
205+
206+
// list needs to be [1, 3]
207+
let current = list.getHead();
208+
209+
// element 1
210+
expect(current).to.not.be.an('undefined');
211+
if (current) {
212+
expect(current.element).to.not.be.an('undefined');
213+
expect(current.element).to.equal(1);
214+
expect(current.next).to.not.be.an('undefined');
215+
if (current.next) {
216+
expect(current.next.element).to.equal(3);
217+
current = current.next;
218+
}
219+
}
220+
221+
// element 3
222+
expect(current).to.not.be.an('undefined');
223+
if (current) {
224+
expect(current.element).to.not.be.an('undefined');
225+
expect(current.element).to.equal(3);
226+
expect(current.next).to.be.an('undefined');
227+
}
228+
});
229+
230+
it('removes element from end of list', () => {
231+
let element;
232+
233+
pushesElements();
234+
235+
const maxIndex = max;
236+
for (let i = maxIndex; i >= min; i--) {
237+
element = list.removeAt(i - 1);
238+
expect(element).to.not.be.an('undefined');
239+
expect(element).to.equal(i);
240+
max--;
241+
verifyList();
242+
}
243+
});
244+
245+
it('returns the head of the list', () => {
246+
expect(list.getHead()).to.be.an('undefined');
247+
248+
list.push(1);
249+
expect(list.getHead()).to.not.be.an('undefined');
250+
});
251+
252+
it('returns the correct size', () => {
253+
expect(list.size()).to.equal(0);
254+
255+
for (let i = min; i <= max; i++) {
256+
list.push(i);
257+
expect(list.size()).to.equal(i);
258+
}
259+
260+
const size = max;
261+
for (let i = min; i <= max; i++) {
262+
list.remove(i);
263+
expect(list.size()).to.equal(size - i);
264+
}
265+
266+
expect(list.size()).to.equal(0);
267+
});
268+
269+
it('returns if it is empty', () => {
270+
expect(list.isEmpty()).to.equal(true);
271+
for (let i = min; i <= max; i++) {
272+
list.push(i);
273+
expect(list.isEmpty()).to.equal(false);
274+
}
275+
276+
for (let i = min; i < max; i++) {
277+
list.remove(i);
278+
expect(list.isEmpty()).to.equal(false);
279+
}
280+
list.remove(max);
281+
expect(list.isEmpty()).to.equal(true);
282+
283+
pushesElements();
284+
expect(list.isEmpty()).to.equal(false);
285+
286+
list.clear();
287+
expect(list.isEmpty()).to.equal(true);
288+
});
289+
290+
it('clears the list', () => {
291+
expect(list.size()).to.equal(0);
292+
list.clear();
293+
expect(list.size()).to.equal(0);
294+
pushesElements();
295+
expect(list.size()).to.greaterThan(0);
296+
list.clear();
297+
expect(list.size()).to.equal(0);
298+
});
299+
300+
it('returns toString primitive types', () => {
301+
expect(list.toString()).to.equal('');
302+
303+
list.push(1);
304+
expect(list.toString()).to.equal('1');
305+
306+
list.push(2);
307+
expect(list.toString()).to.equal('1,2');
308+
309+
list.clear();
310+
expect(list.toString()).to.equal('');
311+
});
312+
313+
function stringCompare(a: string, b: string): number {
314+
return a.localeCompare(b);
315+
}
316+
317+
it('returns toString primitive types: string', () => {
318+
319+
const ds = new SortedLinkedList<string>(util.defaultEquals, stringCompare);
320+
ds.push('el2');
321+
expect(ds.toString()).to.equal('el2');
322+
323+
ds.push('el1');
324+
expect(ds.toString()).to.equal('el1,el2');
325+
});
326+
327+
function myObjCompare(a: MyObj, b: MyObj): number {
328+
return a.toString().localeCompare(b.toString());
329+
}
330+
331+
it('returns toString objects', () => {
332+
const ds = new SortedLinkedList<MyObj>(util.defaultEquals, myObjCompare);
333+
expect(ds.toString()).to.equal('');
334+
335+
ds.push(new MyObj(3, 4));
336+
expect(ds.toString()).to.equal('3|4');
337+
338+
ds.push(new MyObj(1, 2));
339+
expect(ds.toString()).to.equal('1|2,3|4');
340+
});
341+
});

‎tsconfig.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,16 @@
1919
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
2020

2121
/* Strict Type-Checking Options */
22-
"strict": true /* Enable all strict type-checking options. */
23-
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
22+
// "strict": true /* Enable all strict type-checking options. */
23+
"noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
2424
// "strictNullChecks": true, /* Enable strict null checks. */
25-
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
26-
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
25+
"noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
26+
"alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
2727

2828
/* Additional Checks */
29-
// "noUnusedLocals": true, /* Report errors on unused locals. */
30-
// "noUnusedParameters": true, /* Report errors on unused parameters. */
31-
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
29+
"noUnusedLocals": true, /* Report errors on unused locals. */
30+
"noUnusedParameters": true, /* Report errors on unused parameters. */
31+
"noImplicitReturns": true /* Report error when not all code paths in function return a value. */
3232
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
3333

3434
/* Module Resolution Options */

0 commit comments

Comments
 (0)
Please sign in to comment.