From 52e07cc8e5a7b35f1c775ad76a685594de321faf Mon Sep 17 00:00:00 2001 From: Manuel Kiessling Date: Wed, 11 Apr 2012 18:52:44 +0200 Subject: [PATCH] optimized mergesort with arrays --- lib/algorithm/mergesortArray.js | 61 +++++++++++++++++++ .../lib/algorithm/mergesortArray.perf.html | 40 ++++++++++++ .../lib/algorithm/mergesortArray.perf.js | 39 ++++++++++++ spec/algorithm/mergesortArray.spec.js | 25 ++++++++ 4 files changed, 165 insertions(+) create mode 100644 lib/algorithm/mergesortArray.js create mode 100644 performance/lib/algorithm/mergesortArray.perf.html create mode 100644 performance/lib/algorithm/mergesortArray.perf.js create mode 100644 spec/algorithm/mergesortArray.spec.js diff --git a/lib/algorithm/mergesortArray.js b/lib/algorithm/mergesortArray.js new file mode 100644 index 0000000..17f1a3f --- /dev/null +++ b/lib/algorithm/mergesortArray.js @@ -0,0 +1,61 @@ +"use strict"; +if (typeof define !== 'function') { var define = require('amdefine')(module) } + +define([], function() { + + var split = function(list) { + var halfsize = Math.floor(list.length / 2); + var left = list.splice(0, halfsize); + var right = list; + return { + left: left, + right: right + } + }; + + var merge = function(left, right, compare) { + var merged = []; + var leftLength = left.length; + var rightLength = right.length; + var leftIndex = 0; + var rightIndex = 0; + while (leftIndex < leftLength && rightIndex < rightLength) { + if (compare(left[leftIndex], right[rightIndex]) <= 0) { // item in left is smaller or equal + merged.push(left[leftIndex]); + leftIndex++; + } else { + merged.push(right[rightIndex]); + rightIndex++; + } + } + + while (leftIndex < leftLength) { + merged.push(left[leftIndex]); + leftIndex++; + } + + while (rightIndex < rightLength) { + merged.push(right[rightIndex]); + rightIndex++; + } + + return merged; + }; + + var mergesort = function(list, compare) { + if (list.length <= 1) { + return list; + } else { + var sublists = split(list); + var sublistleft = sublists.left; + var sublistright = sublists.right; + + var left = mergesort(sublistleft, compare); + var right = mergesort(sublistright, compare); + + return merge(left, right, compare); + } + }; + + return mergesort; +}); diff --git a/performance/lib/algorithm/mergesortArray.perf.html b/performance/lib/algorithm/mergesortArray.perf.html new file mode 100644 index 0000000..15b0c53 --- /dev/null +++ b/performance/lib/algorithm/mergesortArray.perf.html @@ -0,0 +1,40 @@ + + + + Performance/Memory test page for mergesortArray.js + + + + + + + diff --git a/performance/lib/algorithm/mergesortArray.perf.js b/performance/lib/algorithm/mergesortArray.perf.js new file mode 100644 index 0000000..4e1741f --- /dev/null +++ b/performance/lib/algorithm/mergesortArray.perf.js @@ -0,0 +1,39 @@ +"use strict"; +if (typeof define !== 'function') { var define = require('amdefine')(module) } + +var compareNumbers = function(a, b) { + if (a < b) { + return -1; + } + if (a === b) { + return 0; + } + if (a > b) { + return 1; + } +}; + +define(["../../../lib/datastructure/Queue", "../../../lib/algorithm/mergesortArray"], function(Queue, mergesort) { + var compareNumbers = function(a, b) { + if (a < b) { + return -1; + } + if (a === b) { + return 0; + } + if (a > b) { + return 1; + } + }; + + var items = []; + for (var i = 0; i < 10000000; i++) { + items.push(Math.floor(Math.random() * 10000000)); + } + + var start = new Date().getTime(); + var sorted = mergesort(items, compareNumbers); + var end = new Date().getTime(); + var time = end - start; + console.log(time); +}); diff --git a/spec/algorithm/mergesortArray.spec.js b/spec/algorithm/mergesortArray.spec.js new file mode 100644 index 0000000..2c2e3f9 --- /dev/null +++ b/spec/algorithm/mergesortArray.spec.js @@ -0,0 +1,25 @@ +"use strict"; +if (typeof define !== 'function') { var define = require('amdefine')(module) } + +var compareNumbers = function(a, b) { + if (a < b) { + return -1; + } + if (a === b) { + return 0; + } + if (a > b) { + return 1; + } +}; + +define(["../../lib/algorithm/mergesortArray"], function(mergesort) { + describe("mergesort", function() { + it("correctly sorts", function() { + var unsorted = [4, 9, 7, 8, 1, 9]; + + var sorted = mergesort(unsorted, compareNumbers); + expect(sorted.join("")).toEqual("147899"); + }); + }); +});