|
1 | | -const { Array2DTracer, Randomize } = require('algorithm-visualizer'); |
| 1 | +// import visualization libraries { |
| 2 | +const { Array1DTracer, Array2DTracer, ChartTracer, Randomize } = require('algorithm-visualizer'); |
| 3 | +// } |
2 | 4 |
|
3 | | -const maxValue = 100; |
4 | | -const arraySize = 10; |
5 | | -const numBuckets = 5; |
| 5 | +// define tracer variables { |
| 6 | +const chartTracer = new ChartTracer('Chart'); |
| 7 | +const arrayTracer = new Array1DTracer('Array'); |
| 8 | +const bucketsTracer = new Array2DTracer('Buckets'); |
| 9 | +// } |
6 | 10 |
|
7 | | -// initialize array values |
8 | | -const array = new Randomize.Array1D(arraySize, new Randomize.Integer(0, maxValue - 1)).create(); |
9 | | -const buckets = []; |
10 | | -const bucketsCount = []; |
11 | | -const sortedArray = []; |
12 | | -for (let i = 0; i < arraySize; i++) { |
13 | | - if (i < numBuckets) { |
14 | | - buckets[i] = []; |
15 | | - bucketsCount[i] = 0; |
16 | | - } |
17 | | - sortedArray[i] = 0; |
18 | | -} |
19 | | -const D = [ |
20 | | - array, |
21 | | - bucketsCount, |
22 | | - sortedArray, |
23 | | -]; |
| 11 | +// define input variables |
| 12 | +const N = 25; // the size of an array |
| 13 | +const K = 5; // the number of buckets |
| 14 | +const array = new Randomize.Array1D(N, new Randomize.Integer(0, 999)).create(); |
| 15 | + |
| 16 | +(function main() { |
| 17 | + // create K buckets |
| 18 | + const buckets = [...new Array(K)].map(() => []); |
| 19 | + // visualize { |
| 20 | + arrayTracer |
| 21 | + .chart(chartTracer) |
| 22 | + .set(array); |
| 23 | + bucketsTracer |
| 24 | + .set(buckets) |
| 25 | + .delay(); |
| 26 | + // } |
24 | 27 |
|
25 | | -const tracer = new Array2DTracer(); |
26 | | -tracer.set(D).delay(); |
| 28 | + // find the maximum value that will be used for distribution |
| 29 | + const max = Math.max(...array); |
27 | 30 |
|
28 | | -// place numbers into appropriate buckets |
29 | | -for (let i = 0; i < array.length; i++) { |
30 | | - const bucketPos = Math.floor(numBuckets * (array[i] / maxValue)); |
31 | | - buckets[bucketPos].push(array[i]); |
32 | | - bucketsCount[bucketPos]++; |
33 | | - tracer.select(0, i).delay(); |
34 | | - tracer.patch(1, bucketPos, D[1][bucketPos]).delay(); |
35 | | - tracer.deselect(0, i); |
36 | | - tracer.depatch(1, bucketPos, D[1][bucketPos]); |
37 | | -} |
| 31 | + // distribute the elements into the buckets |
| 32 | + for (let i = 0; i < N; i++) { |
| 33 | + const number = array[i]; |
| 34 | + const bucketIndex = Math.floor(number / (max + 1) * K); |
| 35 | + const bucket = buckets[bucketIndex]; |
| 36 | + bucket.push(number); |
| 37 | + // visualize { |
| 38 | + arrayTracer.select(i); |
| 39 | + bucketsTracer |
| 40 | + .patch(bucketIndex, bucket.length - 1, number) |
| 41 | + .delay() |
| 42 | + .depatch(bucketIndex, bucket.length - 1); |
| 43 | + // } |
38 | 44 |
|
39 | | -let sortLocation = 0; |
40 | | -for (let k = 0; k < buckets.length; k++) { |
41 | | - // do insertion sort |
42 | | - for (let i = 1; i < buckets[k].length; i++) { |
43 | | - const key = buckets[k][i]; |
44 | | - let j; |
45 | | - for (j = i - 1; (j >= 0) && (buckets[k][j] > key); j--) { |
46 | | - buckets[k][j + 1] = buckets[k][j]; |
| 45 | + // insertion sort within the bucket |
| 46 | + let j = bucket.length - 1; |
| 47 | + while (j > 0 && bucket[j - 1] > bucket[j]) { |
| 48 | + const temp = bucket[j - 1]; |
| 49 | + bucket[j - 1] = bucket[j]; |
| 50 | + bucket[j] = temp; |
| 51 | + // visualize { |
| 52 | + bucketsTracer |
| 53 | + .patch(bucketIndex, j - 1, bucket[j - 1]) |
| 54 | + .patch(bucketIndex, j, bucket[j]) |
| 55 | + .delay() |
| 56 | + .depatch(bucketIndex, j - 1) |
| 57 | + .depatch(bucketIndex, j); |
| 58 | + // } |
| 59 | + j--; |
47 | 60 | } |
48 | | - buckets[k][j + 1] = key; |
| 61 | + // visualize { |
| 62 | + arrayTracer.deselect(i); |
| 63 | + // } |
49 | 64 | } |
50 | 65 |
|
51 | | - // place ordered buckets into sorted array |
52 | | - for (let i = 0; i < buckets[k].length; i++) { |
53 | | - sortedArray[sortLocation] = buckets[k][i]; |
54 | | - bucketsCount[k]--; |
55 | | - tracer.patch(1, k, D[1][k]); |
56 | | - tracer.patch(2, sortLocation, D[2][sortLocation]).delay(); |
57 | | - tracer.depatch(1, k, D[1][k]); |
58 | | - tracer.depatch(2, sortLocation, D[2][sortLocation]); |
59 | | - sortLocation++; |
| 66 | + // concatenate the buckets back into the array |
| 67 | + let i = 0; |
| 68 | + for (let bucketIndex = 0; bucketIndex < K; bucketIndex++) { |
| 69 | + const bucket = buckets[bucketIndex]; |
| 70 | + for (let j = 0; j < bucket.length; j++) { |
| 71 | + array[i] = bucket[j]; |
| 72 | + // visualize { |
| 73 | + arrayTracer.patch(i, array[i]); |
| 74 | + bucketsTracer |
| 75 | + .select(bucketIndex, j) |
| 76 | + .delay() |
| 77 | + .deselect(bucketIndex, j); |
| 78 | + arrayTracer.depatch(i); |
| 79 | + // } |
| 80 | + i++; |
| 81 | + } |
60 | 82 | } |
61 | | -} |
| 83 | +})(); |
0 commit comments