1 |
|
2 | var SortingAnimations;
|
3 | 'use strict';
|
4 | SortingAnimations = function (canvas) {
|
5 | var ctx, lineWidth, updateCost, compareCost, randomArray, paint, compareAsync, swapAsync, assignAsync, sortOperations, self;
|
6 | ctx = canvas.getContext ? canvas.getContext('2d') : null;
|
7 | lineWidth = 9;
|
8 | updateCost = 50;
|
9 | compareCost = 30;
|
10 | randomArray = function () {
|
11 | var array, length, i;
|
12 | array = [];
|
13 | length = Math.floor(canvas.width / (lineWidth + 1));
|
14 | i = 1;
|
15 | while (i <= length) {
|
16 | array.push(i);
|
17 | i++;
|
18 | }
|
19 | array.sort(function () {
|
20 | return Math.round(Math.random()) - 0.5;
|
21 | });
|
22 | return array;
|
23 | };
|
24 | paint = function (array, updating) {
|
25 | var i, x, height;
|
26 | ctx.clearRect(0, 0, canvas.width, canvas.height);
|
27 | ctx.lineWidth = lineWidth;
|
28 | i = 0;
|
29 | while (i < array.length) {
|
30 | x = (lineWidth + 1) * i + lineWidth / 2;
|
31 | height = array[i] * (lineWidth + 1) * canvas.height / canvas.width;
|
32 | ctx.beginPath();
|
33 | if (updating && updating.indexOf(i) >= 0) {
|
34 | ctx.strokeStyle = 'red';
|
35 | } else {
|
36 | ctx.strokeStyle = 'black';
|
37 | }
|
38 | ctx.moveTo(x, canvas.height);
|
39 | ctx.lineTo(x, canvas.height - height);
|
40 | ctx.stroke();
|
41 | i++;
|
42 | }
|
43 | };
|
44 | compareAsync = function (x, y, callback) {
|
45 | setTimeout(function () {
|
46 | callback(x - y);
|
47 | }, compareCost);
|
48 | };
|
49 | swapAsync = function (array, i, j, callback) {
|
50 | var t;
|
51 | t = array[i];
|
52 | array[i] = array[j];
|
53 | array[j] = t;
|
54 | paint(array, [
|
55 | i,
|
56 | j
|
57 | ]);
|
58 | setTimeout(function () {
|
59 | callback();
|
60 | }, updateCost);
|
61 | };
|
62 | assignAsync = function (array, i, value, updating, callback) {
|
63 | array[i] = value;
|
64 | paint(array, updating);
|
65 | setTimeout(function () {
|
66 | callback();
|
67 | }, updateCost);
|
68 | };
|
69 | sortOperations = {
|
70 | Bubble: function (array, callback) {
|
71 | var i, j, r;
|
72 | i = 0;
|
73 | function loop_1(loop_1_cont) {
|
74 | if (i < array.length) {
|
75 | j = 0;
|
76 | function loop_0(loop_0_cont) {
|
77 | if (j < array.length - i - 1) {
|
78 | compareAsync(array[j], array[j + 1], function () {
|
79 | r = arguments[0];
|
80 | (function (cont) {
|
81 | if (r > 0) {
|
82 | swapAsync(array, j, j + 1, function () {
|
83 | cont();
|
84 | });
|
85 | } else {
|
86 | cont();
|
87 | }
|
88 | }(function () {
|
89 | j++;
|
90 | loop_0(loop_0_cont);
|
91 | }));
|
92 | });
|
93 | } else {
|
94 | loop_0_cont();
|
95 | }
|
96 | }
|
97 | loop_0(function () {
|
98 | i++;
|
99 | loop_1(loop_1_cont);
|
100 | });
|
101 | } else {
|
102 | loop_1_cont();
|
103 | }
|
104 | }
|
105 | loop_1(function () {
|
106 | callback();
|
107 | });
|
108 | },
|
109 | Quick: function (array, callback) {
|
110 | var partitionAsync, sortAsync;
|
111 | partitionAsync = function (begin, end, callback) {
|
112 | var i, j, pivot, r;
|
113 | i = begin;
|
114 | j = end;
|
115 | pivot = array[Math.floor((begin + end) / 2)];
|
116 | function loop_4(loop_4_cont) {
|
117 | if (i <= j) {
|
118 | function loop_2(loop_2_cont) {
|
119 | if (true) {
|
120 | compareAsync(array[i], pivot, function () {
|
121 | r = arguments[0];
|
122 | if (r < 0) {
|
123 | i++;
|
124 | } else {
|
125 | return loop_2_cont();
|
126 | }
|
127 | loop_2(loop_2_cont);
|
128 | });
|
129 | } else {
|
130 | loop_2_cont();
|
131 | }
|
132 | }
|
133 | loop_2(function () {
|
134 | function loop_3(loop_3_cont) {
|
135 | if (true) {
|
136 | compareAsync(array[j], pivot, function () {
|
137 | r = arguments[0];
|
138 | if (r > 0) {
|
139 | j--;
|
140 | } else {
|
141 | return loop_3_cont();
|
142 | }
|
143 | loop_3(loop_3_cont);
|
144 | });
|
145 | } else {
|
146 | loop_3_cont();
|
147 | }
|
148 | }
|
149 | loop_3(function () {
|
150 | (function (cont) {
|
151 | if (i <= j) {
|
152 | swapAsync(array, i, j, function () {
|
153 | i++;
|
154 | j--;
|
155 | cont();
|
156 | });
|
157 | } else {
|
158 | cont();
|
159 | }
|
160 | }(function () {
|
161 | loop_4(loop_4_cont);
|
162 | }));
|
163 | });
|
164 | });
|
165 | } else {
|
166 | loop_4_cont();
|
167 | }
|
168 | }
|
169 | loop_4(function () {
|
170 | callback(i);
|
171 | });
|
172 | };
|
173 | sortAsync = function (begin, end, callback) {
|
174 | var index;
|
175 | partitionAsync(begin, end, function () {
|
176 | index = arguments[0];
|
177 | (function (cont) {
|
178 | if (begin < index - 1) {
|
179 | sortAsync(begin, index - 1, function () {
|
180 | cont();
|
181 | });
|
182 | } else {
|
183 | cont();
|
184 | }
|
185 | }(function () {
|
186 | (function (cont) {
|
187 | if (index < end) {
|
188 | sortAsync(index, end, function () {
|
189 | cont();
|
190 | });
|
191 | } else {
|
192 | cont();
|
193 | }
|
194 | }(function () {
|
195 | callback();
|
196 | }));
|
197 | }));
|
198 | });
|
199 | };
|
200 | sortAsync(0, array.length - 1, function () {
|
201 | callback();
|
202 | });
|
203 | },
|
204 | Selection: function (array, callback) {
|
205 | var j, mi, i, r;
|
206 | j = 0;
|
207 | function loop_6(loop_6_cont) {
|
208 | if (j < array.length - 1) {
|
209 | mi = j;
|
210 | i = j + 1;
|
211 | function loop_5(loop_5_cont) {
|
212 | if (i < array.length) {
|
213 | compareAsync(array[i], array[mi], function () {
|
214 | r = arguments[0];
|
215 | if (r < 0) {
|
216 | mi = i;
|
217 | }
|
218 | i++;
|
219 | loop_5(loop_5_cont);
|
220 | });
|
221 | } else {
|
222 | loop_5_cont();
|
223 | }
|
224 | }
|
225 | loop_5(function () {
|
226 | swapAsync(array, mi, j, function () {
|
227 | j++;
|
228 | loop_6(loop_6_cont);
|
229 | });
|
230 | });
|
231 | } else {
|
232 | loop_6_cont();
|
233 | }
|
234 | }
|
235 | loop_6(function () {
|
236 | callback();
|
237 | });
|
238 | },
|
239 | Shell: function (array, callback) {
|
240 | var gaps, gap, i, temp, j, r;
|
241 | gaps = [
|
242 | 701,
|
243 | 301,
|
244 | 132,
|
245 | 57,
|
246 | 23,
|
247 | 10,
|
248 | 4,
|
249 | 1
|
250 | ];
|
251 | gap = Math.floor(array.length / 2);
|
252 | function loop_9(loop_9_cont) {
|
253 | if (gap > 0) {
|
254 | i = gap;
|
255 | function loop_8(loop_8_cont) {
|
256 | if (i < array.length) {
|
257 | temp = array[i];
|
258 | j = i;
|
259 | function loop_7(loop_7_cont) {
|
260 | if (j >= gap) {
|
261 | compareAsync(temp, array[j - gap], function () {
|
262 | r = arguments[0];
|
263 | (function (cont) {
|
264 | if (r < 0) {
|
265 | assignAsync(array, j, array[j - gap], null, function () {
|
266 | cont();
|
267 | });
|
268 | } else {
|
269 | return loop_7_cont();
|
270 | cont();
|
271 | }
|
272 | }(function () {
|
273 | j -= gap;
|
274 | loop_7(loop_7_cont);
|
275 | }));
|
276 | });
|
277 | } else {
|
278 | loop_7_cont();
|
279 | }
|
280 | }
|
281 | loop_7(function () {
|
282 | assignAsync(array, j, temp, [j], function () {
|
283 | i++;
|
284 | loop_8(loop_8_cont);
|
285 | });
|
286 | });
|
287 | } else {
|
288 | loop_8_cont();
|
289 | }
|
290 | }
|
291 | loop_8(function () {
|
292 | gap = Math.floor(gap / 2);
|
293 | loop_9(loop_9_cont);
|
294 | });
|
295 | } else {
|
296 | loop_9_cont();
|
297 | }
|
298 | }
|
299 | loop_9(function () {
|
300 | callback();
|
301 | });
|
302 | }
|
303 | };
|
304 | this.supported = !!ctx;
|
305 | this.randomArray = randomArray;
|
306 | this.paint = paint;
|
307 | this.names = [];
|
308 | self = this;
|
309 | Object.keys(sortOperations).forEach(function (m) {
|
310 | self.names.push(m);
|
311 | });
|
312 | this.sortAsync = function (name, array, callback) {
|
313 | paint(array);
|
314 | sortOperations[name](array, function () {
|
315 | paint(array);
|
316 | callback();
|
317 | });
|
318 | };
|
319 | }; |
\ | No newline at end of file |