5

I recently wanted to walk somebody through how Array.prototype.sort uses a custom method to compare two values at any given time, and decide whether they should be swapped or left alone. I decided to log the array during each comparison so the result of the previous comparison could be seen. When I logged the array, I noticed something rather odd about the state of the array at certain moments.

Assuming the following:

var num = [ 2, 1, 8, 5, 3 ];

num.sort( comparator );

function comparator ( a, b ) {
    console.log( num ); // Current state of num
    return a - b; // Order values numerically
}

This is the output:

[ 2, 1, 8, 5, 3 ] // Comparing 2 and 1
[ 1, 2, 8, 5, 3 ] // Comparing 2 and 8
[ 1, 2, 8, 5, 3 ] // Comparing 8 and 5
[ 1, 2, 8, 8, 3 ] // Comparing 2 and 5
[ 1, 2, 5, 8, 3 ] // Comparing 8 and 3
[ 1, 2, 5, 8, 8 ] // Comparing 5 and 3
[ 1, 2, 5, 5, 8 ] // Comparing 2 and 3

The array is sorted properly ([ 1, 2, 3, 5, 8 ]) but I am still left scratching my head at some of the passes on the collection itself.

How is it that 8 appears twice on iteration 4, replacing 5 temporarily. And again, 8 appears twice two iterations later replacing 3 temporarily. Lastly, 5 appears twice, temporarily replacing 3 in the last iteration.

Note that the above code was ran in Chrome.

6
  • Now try it with a longer array. Different behavior? Check if there's a difference across the 10-ish boundary; looks insertion-sort-y. 10+ possibly quicksort-y? IIRC it changes depending on size, but it was awhile ago I thought about this. Commented Oct 8, 2013 at 21:48
  • @DaveNewton Interesting idea, but with 13 items it still seems to temporarily duplicate content across compared indexes. Hadn't considered that the implementation might change depending on the size of the collection though. Commented Oct 8, 2013 at 21:50
  • And it's never the items currently being checked console.log(a, b, num); Commented Oct 8, 2013 at 21:53
  • @JonathanSampson I'd still try a meaningfully-longer array, just out of curiosity. Insertion sorts are fast on small sets, IIRC. Commented Oct 8, 2013 at 21:55
  • IIRC, Chrome uses insertion sort for <10 elements, and recursion for >10 elements. Of course, the recursion ends up insert-sorting when it gets to 10. Commented Oct 8, 2013 at 21:55

1 Answer 1

2

Interesting, but not too surprising.

It appears to be using a simple insertion-sort algorithm in this instance.

Something along the lines of:

  • Get item [1]
  • Shift every item below it up one until you find an item that's lower, then put above this item
  • Get item [2]
  • Shift every item below it up one until you find an item that's lower, then put it above this item
  • Get item [3]
  • (cont)

When describing the bubble sort algorithm, you usually imagine each element being swapped along the array until it finds its place. But it's more efficient to store the item into a temporary variable than to swap it.

Sign up to request clarification or add additional context in comments.

5 Comments

I had considered this, but cannot find a reason why some iterations would result in duplicated values, while others would not. If every iteration resulted in duplicated values, followed by a correction, this would have seemed more obvious to me.
this particular version of bubble sort is normally called "inserion sort"
@JonathanSampson only elements that move to the left are temporarily removed in insert-sort
@JanDvorak Woohoo I remembered something!
@JanDvorak Good observation. I would ask why that is, but might spoil some potentially good reading for myself ;)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.