Back to Freecodecamp

Sorting algorithms/Comb sort

curriculum/challenges/english/blocks/rosetta-code-challenges/5a23c84252665b21eecc8005.md

latest3.9 KB
Original Source

--description--

Implement a comb sort.

The Comb Sort is a variant of the Bubble Sort.

Like the Shell sort, the Comb Sort increases the gap used in comparisons and exchanges.

Dividing the gap by $(1-e^{-\varphi})^{-1} \approx 1.247330950103979$ works best, but 1.3 may be more practical.

Some implementations use the insertion sort once the gap is less than a certain amount.

Variants:

<ul> <li>Combsort11 makes sure the gap ends in (11, 8, 6, 4, 3, 2, 1), which is significantly faster than the other two possible endings.</li> <li>Combsort with different endings changes to a more efficient sort when the data is almost sorted (when the gap is small). Comb sort with a low gap isn't much better than the Bubble Sort.</li> </ul>

Pseudocode:

<pre><b>function</b> combsort(<b>array</b> input) gap := input<b>.size</b> <i>//initialize gap size</i> <b>loop until</b> gap = 1 <b>and</b> swaps = 0 <i>//update the gap value for a next comb. Below is an example</i> gap := int(gap / 1.25) <b>if</b> gap &#x3C; 1 <i>//minimum gap is 1</i> gap := 1 <b>end if</b> i := 0 swaps := 0 <i>//see <a href='https://rosettacode.org/wiki/Sorting_algorithms/Bubble_sort' target='_blank'>Bubble Sort</a> for an explanation</i> <i>//a single "comb" over the input list</i> <b>loop until</b> i + gap >= input<b>.size</b> <i>//see <a href='https://rosettacode.org/wiki/Sorting_algorithms/Shell_sort' target='_blank'>Shell sort</a> for similar idea</i> <b>if</b> input[i] > input[i+gap] <b>swap</b>(input[i], input[i+gap]) swaps := 1 <i>// Flag a swap has occurred, so the</i> <i>// list is not guaranteed sorted</i> <b>end if</b> i := i + 1 <b>end loop</b> <b>end loop</b> <b>end function</b> </pre>

--instructions--

Write a function that sorts a given array using Comb sort.

--hints--

combSort should be a function.

js
assert(typeof combSort == 'function');

combSort([25, 32, 12, 7, 20]) should return an array.

js
assert(Array.isArray(combSort([25, 32, 12, 7, 20])));

combSort([25, 32, 12, 7, 20]) should return [7, 12, 20, 25, 32].

js
assert.deepEqual(combSort([25, 32, 12, 7, 20]), [7, 12, 20, 25, 32]);

combSort([38, 45, 35, 8, 13]) should return [8, 13, 35, 38, 45].

js
assert.deepEqual(combSort([38, 45, 35, 8, 13]), [8, 13, 35, 38, 45]);

combSort([43, 36, 20, 34, 24]) should return [20, 24, 34, 36, 43].

js
assert.deepEqual(combSort([43, 36, 20, 34, 24]), [20, 24, 34, 36, 43]);

combSort([12, 33, 26, 18, 1, 16, 38]) should return [1, 12, 16, 18, 26, 33, 38].

js
assert.deepEqual(combSort([12, 33, 26, 18, 1, 16, 38]), [
  1,
  12,
  16,
  18,
  26,
  33,
  38
]);

combSort([3, 39, 48, 16, 1, 4, 29]) should return [1, 3, 4, 16, 29, 39, 48].

js
assert.deepEqual(combSort([3, 39, 48, 16, 1, 4, 29]), [
  1,
  3,
  4,
  16,
  29,
  39,
  48
]);

--seed--

--seed-contents--

js
function combSort(arr) {

}

--solutions--

js
function combSort(arr) {
  function is_array_sorted(arr) {
    var sorted = true;
    for (var i = 0; i < arr.length - 1; i++) {
      if (arr[i] > arr[i + 1]) {
        sorted = false;
        break;
      }
    }
    return sorted;
  }
  var iteration_count = 0;
  var gap = arr.length - 2;
  var decrease_factor = 1.25;

  // Until array is not sorted, repeat iterations
  while (!is_array_sorted(arr)) {
    // If not first gap
    if (iteration_count > 0)
      // Calculate gap
      gap = gap == 1 ? gap : Math.floor(gap / decrease_factor);

    // Set front and back elements and increment to a gap
    var front = 0;
    var back = gap;
    while (back <= arr.length - 1) {
      // If elements are not ordered swap them
      if (arr[front] > arr[back]) {
        var temp = arr[front];
        arr[front] = arr[back];
        arr[back] = temp;
      }

      // Increment and re-run swapping
      front += 1;
      back += 1;
    }
    iteration_count += 1;
  }

  return arr;
}