Linked Lists
2018-03-11
The linked list datat structure
- Disadvantage of Array:
- the size of array is fixed
- inserting or removing items from the beginning or from the middle of the array is expensive, because the elements need to be shifted over.
- Linked Lists
- Linked lists store a sequential collection of elements; but unlike arrays, the elements are not placed contiguously in memory. Each element consists of a node that stores the element itself and also a reference that points to the next element.
- advantage over conventional array: do not need to shift elements over when adding or removing them.
- disadvantage over conventional array: if we want to access an element from the middle, we need to start from the beginning and iterate the list until we find the desired element.
Creating a linked list
1 | function LinkedList(){ |
- Appending elements to the end of the linked list
1 | this.append = function(element){ |
- Removing elements from the linked list
1 | this.removeAt = function(position){ |
Inserting an element at any position
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21this.insert = function(position, element){
if (position >= 0 && position <= length){
let node = new Node(element), current = head, previous, index = 0;
if (position === 0){
node.next = current;
head = node;
} else {
while ( index ++ < position ){
previous = current;
current = current.next;
}
node.next = current;
previous.next = node;
}
length ++;
return true;
}else{
return false;
}
}The
toString()
method1
2
3
4
5
6
7
8
9this.toString = function(){
let current = head, string = '';
while(current){
string += current.element + (current.next ? 'n' : '');
current = current.next;
}
return string;
}The
indexOf
method1
2
3
4
5
6
7
8
9
10
11this.indexOf = function(element){
let current = head, index = -1;
while ( current ){
if ( element === current.element){
return index;
}
index ++;
current = current.next;
}
return -1;
}The
remove()
method1
2
3
4this.remove = function(element){
let index = this.indexOf(element);
return this.removeAt(index);
}The
isEmpty()
,size()
,andgetHead()
methods1
2
3
4
5
6
7
8
9this.isEmpty = function(){
return length === 0;
}
this.size = function(){
return length;
}
this.getHead = function(){
return head;
}The final Version
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94function LinkedLists(){
let head = null, length = 0;
let Node = function(element){
this.element = element;
this.next = null;
}
this.append = function(element){
let node = new Node(element), current;
if(head === null){
head = node;
}else{
while(current.next){
current = current.next;
}
current.next = node;
length ++;
}
}
this.insert = function(position, element){
if (position > -1 && position < length){
let node = new Node(element), current = head, previous;
if (position === 0){
head = node;
node.next = current;
} else {
let index = 0;
while(index ++ < position){
previous = current;
current = current.next;
}
previous.next = node;
node.next = current;
}
length ++;
return true;
}else{
return false;
}
}
this.removeAt = function(position){
if (position > -1 && position < length){
let current = head, previous;
if (position === 0){
head = current.next;
length --;
return current.element;
} else {
let index = 0;
while (index ++ < position){
previous = current;
current = current.next;
}
previous.next = current.next;
length --;
return current.element;
}
} else {
return null;
}
}
this.indexOf = function(element){
let current = head, index = -1;
while(current){
if(element === current.element){
return index;
}else {
index ++;
current = current.next;
}
}
return -1;
}
this.remove = function(element){
let index = this.indexOf(element);
return this.removeAt(index);
}
this.size = function(){
return length;
}
this.isEmpty = function(){
return length === 0;
}
this.toString = function(){
let current = head, string = '';
while(current){
string += current.element;
current = current.next;
}
return string;
}
this.print = function{
console.log( this.toString());
}
}
Doubly linked lists
- In the doubly linked list, we have a double link: one for the next element and one for the previous element.
- Thus, it provides us with two ways to iterate the list: from the beginning to its end and vice versa.
1 | function DoublyLinkedList(){ |
- Removing elements from any position.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29this.removeAt = function(position){
if (position > -1 && position < length){
let current = head, previous, index = 0;
if (position === 0){
head = current.next;
if (length === 1){
tail = null;
} else {
head.prev = null;
}
} else if ( position === length - 1){
current = tail;
tail = current.prev;
tail.next = null;
} else {
while (index ++ < position){
previous = current
current = current.next;
}
previous.next = current.next;
current.next.prev = previous;
}
length --;
return current.element;
} else {
return null;
}
}
Circular Linked Lists
- Circular Linked List: have one reference direction and its last element’s next pointer does not make reference to null, but to the first element - the head.
- doubly circular linked list: have two reference direction and has
tail.next
pointing to thehead
element, andhead.prev
pointing to thetail
element;