Skip to main content
4 of 6
added 1011 characters in body
tsh
  • 525
  • 2
  • 7

Yes, it is short. But it is somehow incorrect.

Time Complexity

Array#splice, Array#unshift will need to move all following element in the list. So it runs under \$O(n)\$ in your case. Your algorithm runs in \$O(n^2)\$ then. But a merge sort should be run in \$O(\log n)\$. As you know... You can write a even shorter code if you try to use Bubble sort as long as you don't care about time complexity.

Try to run your code on my laptop*, time usage is show in table below

Array Size Time Used (ms) Time/Size2 Time/(Size*log(Size))
3000 9.6 1.06e-6 0.92e-3
4000 16.97 1.06e-6 1.17e-3
5000 26.42 1.0e-6 1.42e-3
6000 37.8 1.05e-6 1.66e-3
7000 50.66 1.03e-6 1.88e-3
8000 66.86 1.04e-6 2.14e-3
9000 83.02 1.02e-6 2.33e-3

You can see that your time usage is \$O(n^2)\$ instead of \$O(\log n)\$.

* I'm using node v16.13.0 just in case.

for (i = 1; i <= 10; ++i) {
  const time = []
  const size = i * 1e3;
  for (let i = 0; i < 11; i++) {
    const arr = [...Array(size)].map(_ => Math.random());
    const t0 = performance.now();
    mergeSort(arr);
    const t = performance.now() - t0;
    time.push(t);
  }
  const mid = time.sort((x, y) => x - y)[5];
  console.log("%o\t%o", size, +mid.toFixed(2));
}

Sort Stability

Merge sort should be stable. But yours is not.

Your merge function didn't keep the stable order. However this can be fixed by changing lista[0] < listb[0] to lista[0] <= listb[0].

After that, the merge sort is still unstable. Consider 3 elements input [a, b, c]. What you do is actually merge([c], merge([a], [b])). But it should be merge(merge([a], [b]), [c]). The order here is important as otherwise sort stability will not be held any more.

const arr = [1, 1, 1].map(Object)
const ori = [...arr];
const result = mergeSort(arr);
console.log(result.map(x => ori.indexOf(x))) // [1, 0, 2]
tsh
  • 525
  • 2
  • 7