Skip to content

Commit ad650e0

Browse files
committed
refactored from ES6 classes to factory function to Linked Lists types Data Strucutre
1 parent 668792f commit ad650e0

File tree

4 files changed

+300
-0
lines changed

4 files changed

+300
-0
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
(function (exports) {
2+
const {linked} = require('./linked.proto.module')
3+
4+
Object.assign(exports, {linked})
5+
}((typeof module.exports !== 'undefined') ? module.exports : window))
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
(function (exports) {
2+
const node = (data) => {
3+
const double = [].slice.call(arguments, 1)[0]
4+
const nodeProto = {
5+
data: 'data',
6+
next: null
7+
}
8+
if (double === 'double') {
9+
nodeProto.prev = null
10+
}
11+
return Object.assign(Object.create(nodeProto), {data})
12+
}
13+
14+
// Helper functions
15+
const curry = fn => (...args) => fn.bind(null, ...args)
16+
const compose = (...fns) => data => fns.reduce((v, f) => f(v), data)
17+
18+
// Factory function
19+
const linked = (type) => {
20+
21+
const link = {}
22+
// private variables
23+
let head = null
24+
let current = null
25+
let length = 0
26+
27+
// single responsability
28+
const setHead = (data) => {
29+
head = data
30+
return head
31+
}
32+
const setHead2 = (data) => {
33+
head = data
34+
head.next = head
35+
return head
36+
}
37+
const setCurrent = (data) => {
38+
current = data
39+
return current
40+
}
41+
const setLength = (type) => {
42+
length += (type) ? 1 : -1
43+
}
44+
45+
// Pure functions
46+
const setNext = curry((value, data) => {
47+
value.next = data
48+
return data
49+
})
50+
const setPrev = curry((value, data) => {
51+
if (data !== null) {
52+
data.prev = value
53+
}
54+
return data
55+
})
56+
const setNext2 = curry((value, data) => {
57+
if(data.next === null) {
58+
value.next = head
59+
}
60+
value.next = data
61+
return data
62+
})
63+
const setPrev2 = curry((value, data) => {
64+
if (data === null) {
65+
data = head
66+
} else {
67+
data.prev = value
68+
}
69+
return data
70+
})
71+
72+
// linked list functions
73+
const findPrev = (data) => {
74+
let c = head
75+
while (!(c.next === null)) {
76+
if (c.next.data === data) {
77+
return c
78+
} else {
79+
c = c.next
80+
}
81+
}
82+
return false
83+
}
84+
85+
const add = (data) => {
86+
let args = (!head && !current) ? [setHead] : [setNext(current)]
87+
compose(...args, setCurrent, setLength)(node(data))
88+
}
89+
90+
const add2 = (data) => {
91+
let args = (!head && !current) ? [setHead] : [setNext(current), setPrev(current)]
92+
compose(...args, setCurrent, setLength)(node(data))
93+
}
94+
95+
const add3 = (data) => {
96+
let args = (!head && !current) ? [setHead2] : [setNext2(current), setPrev2(current)]
97+
compose(...args, setCurrent, setLength)(node(data))
98+
}
99+
100+
const remove = (data) => {
101+
let prev = findPrev(data)
102+
if (!(prev.next === null)) {
103+
compose(setCurrent, setNext(prev))(prev.next.next)
104+
}
105+
setLength(false)
106+
}
107+
108+
const remove2 = (data) => {
109+
let prev = findPrev(data)
110+
if (!(prev.next === null)) {
111+
compose(setPrev(prev),setNext(prev), setCurrent)(prev.next.next)
112+
}
113+
setLength(false)
114+
}
115+
116+
const remove3 = (data) => {
117+
let prev = findPrev(data)
118+
if (!(prev.next === null)) {
119+
compose(setPrev2(prev),setNext2(prev), setCurrent)(prev.next.next)
120+
}
121+
setLength(false)
122+
}
123+
124+
link.contains = (data) => {
125+
let c = head
126+
while (!(c === null)) {
127+
if (c.data === data) {
128+
return true
129+
}
130+
c = c.next
131+
}
132+
return false
133+
}
134+
135+
const display = () => {
136+
let c = head
137+
let show = ''
138+
while (!(c === null)) {
139+
show += `${c.data} ${(c.next !== null) ? ' ->' : ''} `
140+
c = c.next
141+
}
142+
return show
143+
}
144+
145+
const display2 = () => {
146+
let c = head
147+
let show = `${c.data} -> `
148+
while (!(c.next.data === head.data)) {
149+
show += `${c.next.data} ${(c.data !== head.data) ? ' ->' : ''} `
150+
c = c.next
151+
}
152+
return show
153+
}
154+
155+
link.getCurrent = () => current
156+
link.getList = () => head
157+
link.size = () => length
158+
159+
// object prototype
160+
const list = Object.create(link)
161+
162+
if (type === 'single') {
163+
Object.assign(list, {add, display, remove})
164+
} else if (type === 'double') {
165+
Object.assign(list, {add: add2, display, remove: remove2})
166+
} else {
167+
Object.assign(list, {add: add3, display: display2, remove: remove3})
168+
}
169+
170+
return list
171+
}
172+
173+
Object.assign(exports, {linked})
174+
}((typeof module.exports !== undefined) ? module.exports : window))
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# Linked List, Double Linked List, Circular Linked List
2+
3+
### Code Examples
4+
5+
- [Linked List Data Structure]('./linked-list.module')
6+
- [Double Linked List Data Structure]('./double-linked-list.module')
7+
- [Circular Linked List Data Structure]('./circular-linked-list.module')
8+
- [Import complete module]('./index')
9+
10+
### Definition Linked List
11+
12+
The simplest form of linked lists — a singly linked list — is a series of nodes where each individual node contains both a value and a pointer to the next node in the list.
13+
14+
common operations you can perform on linked list:
15+
16+
**Additions**
17+
- `add`: grow the list by adding items to the end of the list.
18+
- `addHead`: Similar to our add method above, we always know the position of the head, so no iteration necessary.
19+
- `insertAfter`: have to iterate over the entire list to find the target node that your value should be inserted after.
20+
**Removals**
21+
- `remove`: will always remove from a given position in the list.
22+
23+
**Search**
24+
- `contains`: will search the list for a value.
25+
26+
### Definition Double Linked List
27+
28+
Doubly Linked List is a variation of Linked list in which navigation is possible in both ways, either forward and backward easily as compared to Single Linked List. Following are the important terms to understand the concept of doubly linked list.
29+
30+
- Link − Each link of a linked list can store a data called an element.
31+
32+
- Next − Each link of a linked list contains a link to the next link called Next.
33+
34+
- Prev − Each link of a linked list contains a link to the previous link called Prev.
35+
36+
LinkedList − A Linked List contains the connection link to the first link called First and to the last link called Last.
37+
38+
common operations you can perform on linked list:
39+
40+
**Additions**
41+
- `add`: grow the list by adding items to the end of the list.
42+
- `addHead`: Similar to our add method above, we always know the position of the head, so no iteration necessary.
43+
- `insertAfter`: ave to iterate over the entire list to find the target node that your value should be inserted after.
44+
- `insertLast`: adds an element at the end of the list.
45+
**Removals**
46+
- `remove`: will always remove from a given position in the list.
47+
- `removeLast`: deletes an element from the end of the list.
48+
**Search**
49+
- `contains`: will search the list for a value.
50+
**Display**
51+
- `display`: displays the complete list in a forward manner.
52+
- `displayReverse`: displays the complete list in a backward manner.
53+
54+
55+
### Definition Circular Linked List
56+
57+
Circular Linked List is a variation of Linked list in which the first element points to the last element and the last element points to the first element. Both Singly Linked List and Doubly Linked List can be made into a circular linked list.
58+
59+
Singly Linked List as Circular
60+
61+
In singly linked list, the next pointer of the last node points to the first node
62+
63+
Doubly Linked List as Circular
64+
65+
In doubly linked list, the next pointer of the last node points to the first node and the previous pointer of the first node points to the last node making the circular in both directions.
66+
67+
common operations you can perform on linked list:
68+
69+
**Additions**
70+
- `add`: grow the list by adding items to the end of the list.
71+
**Removals**
72+
- `remove`: will always remove from a given position in the list.
73+
**Search**
74+
- `contains`: will search the list for a value.
75+
**Display**
76+
- `display`: displays the complete list in a forward manner.
77+
78+
### Example use cases
79+
- Storing values in a hash table to prevent collisions
80+
81+
### Resources
82+
83+
- [Data Structure and Algorithms - Linked List](https://www.tutorialspoint.com/data_structures_algorithms/linked_list_algorithms.htm)

06-chapter-Linked-Lists-types/test.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
const {linked} = require('./index')
2+
3+
test('Linked List test', assert => {
4+
const amazingRace = linked('single')
5+
6+
amazingRace.add('Colombo, Sri Lanka')
7+
assert.equal(amazingRace.getCurrent().data, 'Colombo, Sri Lanka', 'can add an element')
8+
9+
amazingRace.add('Lagos, Nigeria')
10+
amazingRace.add('Surat, India')
11+
amazingRace.add('Suzhou, China')
12+
13+
assert.equal(4, amazingRace.size(), 'can get the size of the linked list')
14+
console.log(`contains 'Suzhou, China' ? ${amazingRace.contains('Suzhou, China')}`) // true
15+
console.log(`contains 'Hanoi, Vietnam' ? ${amazingRace.contains('Hanoi, Vietnam')}`) // true
16+
amazingRace.add('Hanoi, Vietnam')
17+
console.log(`contains 'Seattle, Washington' ? ${amazingRace.contains('Seattle, Washington')}`) // true
18+
amazingRace.add('Seattle, Washington')
19+
console.log(`contains 'North Pole' ? ${amazingRace.contains('North Pole')}`) // true
20+
amazingRace.add('North Pole')
21+
22+
amazingRace.remove('North Pole')
23+
amazingRace.remove('Hanoi, Vietnam')
24+
assert.equal(amazingRace.size(), 5, 'can remove elements')
25+
})
26+
27+
test('Double Linked List test', assert => {
28+
const amazingRace = linked('double')
29+
30+
amazingRace.add('Colombo, Sri Lanka')
31+
32+
assert.equal(amazingRace.getCurrent().data, 'Colombo, Sri Lanka', 'can add an element')
33+
34+
amazingRace.add('Lagos, Nigeria')
35+
amazingRace.add('Surat, India')
36+
amazingRace.add('Suzhou, China')
37+
assert.equal(amazingRace.getCurrent().prev.data, 'Surat, India', 'double linked list')
38+
})

0 commit comments

Comments
 (0)