Skip to content

Commit bacfd56

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

14 files changed

+1625
-13
lines changed

.vscode/settings.json

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"typescript.tsdk": "node_modules/typescript/lib"
3+
}

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Work in Progress.
1414
* 02: [Arrays](https://github.com/loiane/javascript-datastructures-algorithms/tree/third-edition/examples/chapter02)
1515
* 03: [Stacks](https://github.com/loiane/javascript-datastructures-algorithms/tree/third-edition/examples/chapter03)
1616
* 04: [Queues and Deques](https://github.com/loiane/javascript-datastructures-algorithms/tree/third-edition/examples/chapter04)
17+
* 05: [LinkedLists](https://github.com/loiane/javascript-datastructures-algorithms/tree/third-edition/examples/chapter05)
1718

1819
## Thrid Edition Updates
1920

examples/PacktDataStructuresAlgorithms.min.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+6-6
Original file line numberDiff line numberDiff line change
@@ -55,24 +55,24 @@
5555
"@types/mocha": "^2.2.42",
5656
"babel-cli": "^6.26.0",
5757
"babel-core": "^6.26.0",
58-
"babel-eslint": "^8.0.0",
58+
"babel-eslint": "^8.0.1",
5959
"babel-loader": "^7.1.2",
6060
"babel-plugin-add-module-exports": "^0.2.1",
6161
"babel-plugin-transform-es2015-modules-umd": "^6.24.1",
6262
"babel-preset-env": "^1.6.0",
6363
"chai": "^4.1.2",
6464
"codecov": "^2.3.0",
65-
"eslint": "^4.6.1",
66-
"eslint-config-airbnb-base": "^12.0.0",
65+
"eslint": "^4.8.0",
66+
"eslint-config-airbnb-base": "^12.0.2",
6767
"eslint-plugin-import": "^2.7.0",
6868
"istanbul": "^v1.1.0-alpha.1",
69-
"mocha": "^3.5.0",
69+
"mocha": "^4.0.1",
7070
"mochawesome": "^2.3.1",
7171
"nyc": "^11.2.1",
7272
"ts-node": "^3.3.0",
7373
"tslint": "^5.7.0",
74-
"typescript": "^2.5.2",
75-
"webpack": "^3.6.0",
74+
"typescript": "^2.6.0-dev.20171014",
75+
"webpack": "^3.7.1",
7676
"yargs": "^9.0.1"
7777
}
7878
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
import { defaultEquals, IEqualsFunction } from '../util';
2+
import { Node } from './models/linked-list-models';
3+
4+
export default class CircularLinkedList<T> {
5+
private count = 0;
6+
private head: Node<T> | undefined;
7+
8+
constructor(private equalsFn: IEqualsFunction<T> = defaultEquals) { }
9+
10+
private getLastElement() {
11+
let current = this.head;
12+
for (let i = 2; i <= this.size() && current; i++) {
13+
current = current.next;
14+
}
15+
return current;
16+
}
17+
18+
push(element: T) {
19+
const node = new Node(element);
20+
let current;
21+
22+
if (this.head === undefined || this.head === null) {
23+
this.head = node;
24+
} else {
25+
current = this.getLastElement();
26+
if (current) {
27+
current.next = node;
28+
}
29+
}
30+
31+
// set node.next to head - to have circular list
32+
node.next = this.head;
33+
34+
this.count++;
35+
}
36+
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+
50+
insert(index: number, element: T) {
51+
if (index >= 0 && index <= this.count) {
52+
const node = new Node(element);
53+
let current = this.head;
54+
55+
if (index === 0) {
56+
if (!this.head) {
57+
// if no node in list
58+
this.head = node;
59+
node.next = this.head;
60+
} else {
61+
node.next = current;
62+
current = this.getLastElement();
63+
// update last element
64+
this.head = node;
65+
if (current) {
66+
current.next = this.head;
67+
}
68+
}
69+
} else {
70+
const previous = this.getElementAt(index - 1);
71+
if (previous) {
72+
node.next = previous.next;
73+
previous.next = node;
74+
}
75+
}
76+
this.count++;
77+
return true;
78+
}
79+
return false;
80+
}
81+
82+
removeAt(index: number) {
83+
if (index >= 0 && index < this.count) {
84+
let current = this.head;
85+
86+
if (index === 0) {
87+
const removed = this.head;
88+
89+
if (this.size() === 1) {
90+
this.head = undefined;
91+
} else {
92+
current = this.getLastElement();
93+
if (this.head) {
94+
this.head = this.head.next;
95+
}
96+
if (current) {
97+
current.next = this.head;
98+
}
99+
current = removed;
100+
}
101+
} else {
102+
// no need to update last element for circular list
103+
const previous = this.getElementAt(index - 1);
104+
if (previous) {
105+
current = previous.next;
106+
if (current) {
107+
previous.next = current.next;
108+
}
109+
}
110+
}
111+
if (current) {
112+
this.count--;
113+
return current.element;
114+
}
115+
}
116+
return undefined;
117+
}
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+
}
166+
}

0 commit comments

Comments
 (0)