How to animate the following quicksort algorithm in javascript?

Viewed 678

I'm trying to learn more about programing and sorting algorithms in general and i wanted to create an animation of a quicksort algorithm using div's with different heights. I've created the sorting algorithm. Running the code snippet will help you understand what i'm trying to do. Here is the code but after the sorting is done it only shows the final result and not the whole process:

function createColumns() {
  $('.column').remove();
  var content = $('#content');
  var columnNumber = $('input:text').val();
  var columnWidth = ((content.width() * 99 / 100) / columnNumber) + 'px';
  for (var i = 0; i < columnNumber; i++) {
    var randomColor = '#' + ('000000' + Math.floor(Math.random() * 16777215).toString(16)).slice(-6);
    var columnHeight = Math.floor(Math.random() * (columnNumber - 1)) + 1;
    $('<div/>', {
      'class': 'column'
    }).css({
      'height': columnHeight + 'px',
      'width': columnWidth,
      'background-color': randomColor
    }).appendTo(content);
  }
}


function quickSort(columns, left, right) {
  var index;
  if (columns.length > 1) {
    index = partition(columns, left, right);
    if (left < (index - 1)) {
      quickSort(columns, left, (index - 1));
    }
    if (index < right) {
      quickSort(columns, index, right);
    }
  }

  return columns;

}

function partition(columns, left, right) {
  var pivot = $(columns[Math.floor((right + left) / 2)]),
    i = left,
    j = right;
  while (i <= j) {
    while ($(columns[i]).height() < pivot.height()) {
      i++
    }
    while ($(columns[j]).height() > pivot.height()) {
      j--;
    }
    if (i <= j) {
      swap(columns, i, j);
      i++;
      j--;
    }
  }
  return i;
}

function swap(columns, firstIndex, secondIndex) {
  var temp, visualTemp;

  visualTemp = columns[secondIndex];
  $(columns[firstIndex]).insertAfter($(columns[secondIndex]));
  $(visualTemp).insertBefore($(columns[firstIndex + 1]));

  temp = columns[firstIndex];
  columns[firstIndex] = columns[secondIndex];
  columns[secondIndex] = temp;
}


$('input').change(function() {
  createColumns();
});

$('#quickSort').click(function() {
  var columns = $('.column');
  var left = 0,
    right = columns.length - 1;

  quickSort(columns, left, right);
});

createColumns();
body {
  padding: 2em;
}

#content {
  width: 100%;
  height: 200px;
  border: 2px solid black;
  position: relative;
  overflow: hidden;
}

.column {
  float: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Number of columns: <input type="text" value="100" />
<div id="content">
</div>
<input type="button" id="quickSort" name="QuickSort" value="Quick Sort">

1 Answers

While it's not quite animated, you can slow the sorting process down a bit if you wrap the internals of your quickSort function in a setTimeout with a small delay (i've chosen 750ms) to see each step.

function createColumns() {
  $('.column').remove();
  var content = $('#content');
  var columnNumber = $('input:text').val();
  var columnWidth = ((content.width() * 99 / 100) / columnNumber) + 'px';
  for (var i = 0; i < columnNumber; i++) {
    var randomColor = '#' + ('000000' + Math.floor(Math.random() * 16777215).toString(16)).slice(-6);
    var columnHeight = Math.floor(Math.random() * (columnNumber - 1)) + 1;
    $('<div/>', {
      'class': 'column'
    }).css({
      'height': columnHeight + 'px',
      'width': columnWidth,
      'background-color': randomColor
    }).appendTo(content);
  }
}


function quickSort(columns, left, right) {
  var index;

  setTimeout(function() {


    if (columns.length > 1) {
      index = partition(columns, left, right);
      if (left < (index - 1)) {

        quickSort(columns, left, (index - 1));
      }
      if (index < right) {
        quickSort(columns, index, right);
      }
    }

    return columns;
  }, 750);

}

function partition(columns, left, right) {
  var pivot = $(columns[Math.floor((right + left) / 2)]),
    i = left,
    j = right;
  while (i <= j) {
    while ($(columns[i]).height() < pivot.height()) {
      i++
    }
    while ($(columns[j]).height() > pivot.height()) {
      j--;
    }
    if (i <= j) {
      swap(columns, i, j);
      i++;
      j--;
    }
  }
  return i;
}

function swap(columns, firstIndex, secondIndex) {
  var temp, visualTemp;

  visualTemp = columns[secondIndex];
  $(columns[firstIndex]).insertAfter($(columns[secondIndex]));
  $(visualTemp).insertBefore($(columns[firstIndex + 1]));

  temp = columns[firstIndex];
  columns[firstIndex] = columns[secondIndex];
  columns[secondIndex] = temp;
}


$('input').change(function() {
  createColumns();
});

$('#quickSort').click(function() {
  var columns = $('.column');
  var left = 0,
    right = columns.length - 1;

  quickSort(columns, left, right);
});

createColumns();
body {
  padding: 2em;
}

#content {
  width: 100%;
  height: 200px;
  border: 2px solid black;
  position: relative;
  overflow: hidden;
}

.column {
  float: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Number of columns: <input type="text" value="100" />
<div id="content">
</div>
<input type="button" id="quickSort" name="QuickSort" value="Quick Sort">

Related