-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathsorting&searching.js
More file actions
297 lines (237 loc) · 9.91 KB
/
sorting&searching.js
File metadata and controls
297 lines (237 loc) · 9.91 KB
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
/**
* before we search an algorithm, we have to sort it
*/
// let's create an array that we will sort and search
function ArrayList () {
var array = [];
this.insert = function (item) {
array.push(item);
}
this.toString = function () {
return array.join();
}
}
// THE BUBBLE SORT
// this is the simplest but worst-case sorting algorithm with respect to time
//it compares every two adjacent items and swaps them if the first one is bigger than the second one
this.bubbleSort = function () {
var length = array.length;
for (let i=0; i<length; i++) {
for (let j=0; j<length-1; j++) {
if (array[j] > array[j+1]) {
swap(array, j, j+1);
}
}
}
}
// now we declare the swap function (this is a private function that is only available only to the code inside the Arraylist class)
var swap = function (array, index1, index2) {
var aux = araay[index1];
array[index1] = array[index2];
array[index2] = aux;
}
// THE IMPROVED BUBBLE SORT
this.modifiedBubleSort = function () {
var length = array.length;
for (let i=0; i<length; i++) {
for (let j=0; j<length-1-i; j++) {
if (array[j] > array[j+1]) {
swap(j, j+1);
}
}
}
}
// THE SELECTION SORT
// the selection sort finds the min value, places it in the first position, the second min value in the 2nd position and so on.
this.selectionSort = function () {
var length = array.length,
indexMin;
for (let i = 0; i <length; i++) {
indexMin = i;
for (var j=0; j<length; j++) {
if (array[indexMin] > array[j]) {
indexMin = j;
}
}
if (i !== indexMin) {
swap(i, indexMin);
}
}
}
// THE INSERTION SORT
// this sorts assumes that the first item is sorted then it compares whether the next item should be placed infront of the first or stay where it is
this.insertionSort = function () {
var length = array.length,
j,
temp;
for (let i = 0; i; i<length; i++) {
j = i;
temp = array[i];
while (j>0 && array[j-1] > temp) {
array[j] = array[j-1];
j--;
}
array[j] = temp;
}
};
// THE MERGE SORT (divide and conquer algorithm)
// this has a better performance with a complexity of 0(n log n);
this.mergeSort = function () {
array = mergeSortRec(array);
}
// mergeSortRec() helper function
var mergeSortRec = function (array) {
var length = array.length;
if (length === 1) {
return array;
}
var mid = Math.floor(length / 2),
left = array.slice(0, mid),
right = array.slice(mid, length);
return merge(mergeSortRec(left), mergeSortRec(right));
}
//merge() helper function
var merge = function (left, right) {
var result = [],
il = 0,
ir = 0;
while (il < left.length && ir < right.length) {
if (left[il] < right[ir]) {
result.push(left[il++]);
} else {
result.push(right[ir++]);
}
}
while (il < left.length) {
result.push(left[il++]);
}
while (ir < right.length) {
result.push(right[ir++]);
}
return result;
}
/*
THE QUICK SORT
This is probably the most used sorting algorithm
it has an 0(n log n) complexity but usually performs better than any other algorithm with the same complexity
this is how it is implemented
1. first, we need to select an item from the array called pivot, which is the middle item of the array.
2. this creates two pointers, the left pointer that points to the first item and the right pointer that points to the last item in the array
3. we now move the left pointer until we find an item that is greater than the pivot and we move the right pointer until we find an item that is lesser than the pivot and swap them.
4. we repeat this process until the left hand side pointer passes the right- hand side pointer. this process helps you to have values that are lesser than the pivot on the left and the ones greater than the pivot on the right. this is called the PARTITION OPERATION
5. This process is repeated for the greater values and the lesser values until the data is sorted
*/
this.quickSort = function(array,left, right) {
var index;
if (array.length > 1) {
index = partition(array, left, right);;
if (left < index - 1) {
this.quickSort(array, left, index - 1);
}
if (index > right) {
this.quickSort(array, index, righty);
}
}
}
//the partition process
var partition = function(array, left, right) {
var pivot = array[Math.floor((right + left) / 2)],
i = left,
j = right;
while (i <= j) {
while (array[i] < pivot) {
i++;
}
while (array[j] > pivot) {
j--;
}
if (i <= j) {
swap(array, i, j);
i++;
j++;
}
}
return i;
}
// the swap function is similar to the one we created above but we can swap it with this ES6
[array[index1], array[index2]] = [array[index2], array[index1]]
// THE HEAP SORT
/*
The heap sort treats an array as a binary tree
1. Index 0 is the root of the tree
2. the parent of any node N is N/2 (with the exception of the root node)
3. the left-hand side child of a node L is 2*L
4. the right-hand side of the node R is 2*R+1
*/
this.heapSort = function () {
var heapSize = array.length;
buildHeap(array);
while (heapSize > 1) {
heapSize--;
swap(array, 0, heapSize);
heapify (array, heapSize, 0);
}
}
// the bulidHeap() function
var buildHeap = function (array) {
var heapSize = array.length;
for (var i = Math.floor(array.length /2); i>=0; i--) {
heapify(array, heapSize , i);
}
}
// the heapify() function
var heapify = function(array, heapSize, i) {
var left = i * 2 + 1,
right = i * 2 + 2,
largest = i;
if (left < heapSize && array[left] > array[largest]) {
largest = left;
}
if (right < heapSize && array[right] > array[largest]) {
largest = right;
}
if (largest !== i) {
swap(array, i, largest);
heapify (array, heapSize, largest);
}
}
// SEARCHING ALGORITHMS
// N.B; The search() methods we created in the data structures and algoritms are searching algorithms more so the BINARY SEARCH TREE search() methods.
// THE SEQUENTIAL/LINEAR SEARCH
//This is the most inefficient and basic search algorithm that consist of comparing each element with the one we are looking for
this.sequentialSearch = function (item) {
for (var i=0; i<array.length; i++) {
if (item === array[i]) {
return i;
}
}
return -1;
}
/*
THE BINARY SEARCH
this works like a guessing game e.g someone can say, "I think the number is between 1 and 10"
to make the algorthm work, these steps have to be followed;
1. A value is selected in the middle of the array
2. if the item is the one we are looking for, we are done
3. if the value we are looking for is less than the selected one, then we will go to the left and back to one (lower).
4. if the value we are looking for is larger than the one selected, then we will go to the right and back to 1 (higher)
*/
this.binarySearch = function (item) {
this.quickSort ();
var low = 0,
high = array.length - 1;
mid,
element;
while (low <= high) {
mid = Math.floor((low + high) / 2);
element = array[mid];
if (element < item) {
low = mid + 1;
} else if (element > item) {
high = mid - 1;
} else {
return mid;
}
}
return -1;
}