Skip to content

Commit 1db8388

Browse files
committed
add bottom_up mergesort
1 parent ee4e896 commit 1db8388

File tree

5 files changed

+96
-2
lines changed

5 files changed

+96
-2
lines changed
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
logger._print('original array = [' + D[0].join(', ') + ']');
2+
3+
function mergeSort(start, end) {
4+
if (Math.abs(end - start) <= 1) return;
5+
6+
var mergeFrom = 0, mergeTo = 1, width, i;
7+
for (width = 1; width < end; width = width * 2) {
8+
/**/logger._print('merging arrays of width: ' + width);
9+
for (i = 0; i < end; i = i + 2 * width) {
10+
merge(mergeFrom, i, Math.min(i + width, end), Math.min(i + 2 * width, end), mergeTo);
11+
}
12+
//this could be copy(mergeTo, mergeFrom, start, end);
13+
//but it is more effecient to swap the input arrays
14+
//if you did copy here, you wouldn't need the copy at the end
15+
mergeFrom = (mergeFrom === 0 ? 1 : 0);
16+
mergeTo = 1 - mergeFrom;
17+
}
18+
if (mergeFrom !== 0) {
19+
/**/logger._print('final copy to original');
20+
copy(mergeFrom, mergeTo, start, end);
21+
}
22+
}
23+
24+
function merge(mergeFrom, start, middle, end, mergeTo) {
25+
var i = start, j = middle, k;
26+
//in an actual merge implementation, mergeFrom and mergeTo would be arrays
27+
//here for the ability to trace what is going on better, the arrays are D[mergeFrom] and D[mergeTo]
28+
/**/logger._print('merging segments [' + start + '..' + middle + '] and [' + middle + '..' + end + ']');
29+
/**/tracer._selectRow(mergeFrom, start, end-1)._wait();
30+
/**/tracer._deselectRow(mergeFrom, start, end-1);
31+
32+
for (k = start; k < end; k++) {
33+
/**/if (j < end) {
34+
/**/ tracer._select(mergeFrom, j);
35+
/**/}
36+
/**/if (i < middle) {
37+
/**/ tracer._select(mergeFrom, i);
38+
/**/}
39+
/**/if (i < middle && j < end) {
40+
/**/ logger._print('compare index ' + i + ' and ' + j + ', values: ' + D[mergeFrom][i] + ' and ' + D[mergeFrom][j])._wait();
41+
/**/}
42+
43+
if (i < middle && (j >= end || D[mergeFrom][i] <= D[mergeFrom][j])) {
44+
/**/if (j < end) {
45+
/**/ logger._print('writing smaller value to output');
46+
/**/} else {
47+
/**/ logger._print('copying index ' + j + ' to output');
48+
/**/}
49+
/**/tracer._notify(mergeTo, k, D[mergeFrom][i])._wait();
50+
/**/tracer._denotify(mergeTo, k);
51+
/**/tracer._deselect(mergeFrom, i);
52+
53+
D[mergeTo][k] = D[mergeFrom][i];
54+
i = i + 1;
55+
} else {
56+
/**/if(i < middle) {
57+
/**/ logger._print('writing smaller value to output');
58+
/**/} else {
59+
/**/ logger._print('copying index ' + j + ' to output');
60+
/**/}
61+
/**/tracer._notify(mergeTo, k, D[mergeFrom][j])._wait();
62+
/**/tracer._denotify(mergeTo, k);
63+
/**/tracer._deselect(mergeFrom, j);
64+
65+
D[mergeTo][k] = D[mergeFrom][j];
66+
j = j + 1;
67+
}
68+
}
69+
}
70+
71+
function copy(mergeFrom, mergeTo, start, end) {
72+
var i;
73+
for (i = start; i < end; i++) {
74+
/**/tracer._select(mergeFrom, i);
75+
/**/tracer._notify(mergeTo, i, D[mergeFrom][i])._wait();
76+
77+
D[mergeTo][i] = D[mergeFrom][i];
78+
79+
/**/tracer._deselect(mergeFrom, i);
80+
/**/tracer._denotify(mergeTo, i);
81+
}
82+
}
83+
84+
mergeSort(0, D[0].length);
85+
logger._print('sorted array = [' + D[0].join(', ') + ']');
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
var tracer = new Array2DTracer();
2+
var logger = new LogTracer();
3+
var D = [
4+
Array1D.random(20, 0, 50),
5+
Array1D.random(20, 0, 0)
6+
];
7+
8+
tracer._setData(D);

algorithm/sorting/merge/desc.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"Mergesort": "In computer science, merge sort (also commonly spelled mergesort) is an efficient, general-purpose, comparison-based sorting algorithm. Most implementations produce a stable sort, which means that the implementation preserves the input order of equal elements in the sorted output. Mergesort is a divide and conquer algorithm that was invented by John von Neumann in 1945. A detailed description and analysis of bottom-up mergesort appeared in a report by Goldstine and Neumann as early as 1948.",
2+
"Merge Sort": "In computer science, merge sort (also commonly spelled mergesort) is an efficient, general-purpose, comparison-based sorting algorithm. Most implementations produce a stable sort, which means that the implementation preserves the input order of equal elements in the sorted output. Mergesort is a divide and conquer algorithm that was invented by John von Neumann in 1945. A detailed description and analysis of bottom-up mergesort appeared in a report by Goldstine and Neumann as early as 1948.",
33
"Complexity": {
44
"time": "average O(n log n)",
55
"space": "worst O(n)"
@@ -8,6 +8,7 @@
88
"<a href='https://en.wikipedia.org/wiki/Merge_sort'>Wikipedia</a>"
99
],
1010
"files": {
11-
"basic": "Mergesort"
11+
"bottom_up": "Bottom-up implementation",
12+
"top_down_list": "Top-down implementation using lists"
1213
}
1314
}

0 commit comments

Comments
 (0)