クイックソートアルゴリズムの可視化。The Coding Trainによるコーディングチャレンジを参考にしています。
quicksort sorting visualization
Simulate Algorithm
View Source Code
/*
* @name Quicksort
* @arialabel Bars of random heights are sorted from shortest to tallest left to right. The bars turn sage green and coral as they are sorted
* @frame 710,400
* @description This is a simulation of the Quicksort
* sorting algorithm. We start with an array of bars
* and sort them according to their height in ascending
* order. References taken from a coding challenge by
* The Coding Train.<br><br>
* Quicksort is a divide-and-conquer algorithm: it
* performs sorting by dividing the original array into
* smaller subarrays and solving them independently,
* loosely speaking. It involves picking an element of
* the array as the pivot element and partitioning the
* given array around the picked pivot.<br>
* Partitioning refers to arranging the given array(or
* subarray) in such a way that all elements to the left
* of the pivot element are smaller than it and all
* elements to its right are larger than it. Thus, we have
* a reference point from where we proceed to sort the
* left and right 'halves' of the array, and eventually
* arrive at an array sorted in ascending order.
* <a href="https://www.geeksforgeeks.org/quick-sort/">
* More</a><br>
*/
// width of each bar is taken as 8.
let values = [];
// The array 'states' helps in identifying the pivot index
// at every step, and also the subarray which is being sorted
// at any given time.
let states = [];
// The setup() function is called once when the program
// starts. Here, we fill the array 'values' with random values
// and the array 'states' with a value of -1 for each position.
function setup() {
// createCanvas(710, 400);
createCanvas(windowWidth, windowHeight);
for(let i = 0; i < width/8; i++) {
values.push(random(height));
states.push(-1);
}
quickSort(0, values.length - 1);
}
// The statements in draw() function are executed continuously
// until the program is stopped. Each statement is executed
// sequentially and after the last line is read, the first
// line is executed again.
function draw() {
background(140);
for(let i = 0; i < values.length; i++) {
// color coding
if (states[i] == 0) {
// color for the bar at the pivot index
fill('#E0777D');
} else if (states[i] == 1) {
// color for the bars being sorted currently
fill('#D6FFB7');
} else {
fill(255);
}
rect(i * 8, height - values[i], 8, values[i]);
}
}
async function quickSort(start, end) {
if (start > end) { // Nothing to sort!
return;
}
// partition() returns the index of the pivot element.
// Once partition() is executed, all elements to the
// left of the pivot element are smaller than it and
// all elements to its right are larger than it.
let index = await partition(start, end);
// restore original state
states[index] = -1;
await Promise.all(
[quickSort(start, index - 1),
quickSort(index + 1, end)
]);
}
// We have chosen the element at the last index as
// the pivot element, but we could've made different
// choices, e.g. take the first element as pivot.
async function partition(start, end) {
for (let i = start; i < end; i++) {
// identify the elements being considered currently
states[i] = 1;
}
// Quicksort algorithm
let pivotIndex = start;
// make pivot index distinct
states[pivotIndex] = 0;
let pivotElement = values[end];
for (let i = start; i < end; i++) {
if (values[i] < pivotElement) {
await swap(i, pivotIndex);
states[pivotIndex] = -1;
pivotIndex++;
states[pivotIndex] = 0;
}
}
await swap(end, pivotIndex);
for (let i = start; i < end; i++) {
// restore original state
if (i != pivotIndex) {
states[i] = -1;
}
}
return pivotIndex;
}
// swaps elements of 'values' at indices 'i' and 'j'
async function swap(i, j) {
// adjust the pace of the simulation by changing the
// value
await sleep(25);
let temp = values[i];
values[i] = values[j];
values[j] = temp;
}
// custom helper function to deliberately slow down
// the sorting process and make visualization easy
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}License
Source code is available on GitHub p5.js website legacy.
All examples are licensed under CC BY-NC-SA 4.0.