mirror of
https://github.moeyy.xyz/https://github.com/trekhleb/javascript-algorithms.git
synced 2024-09-20 07:43:04 +08:00
.
This commit is contained in:
parent
ac5f7d4813
commit
8ada0862e6
@ -1,17 +0,0 @@
|
||||
# visual-sort
|
||||
Visualisation of popular sorting algorithms. Made with processing and javascript. Works well on desktop as well as mobile.
|
||||
|
||||
To run locally,
|
||||
1. clone repo
|
||||
2. run index.html
|
||||
3. to view and edit the code, open the repo using an ide.
|
||||
|
||||
![](mergedemo.gif)
|
||||
|
||||
Current List:
|
||||
1. selection sort O(n*n)
|
||||
2. bubble sort O(n*n)
|
||||
3. quick sort O(n*n) worst case, O(n logn) average case
|
||||
4. heap sort O(n logn)
|
||||
5. merge sort O(n logn)
|
||||
|
@ -1,29 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>visual-sort</title>
|
||||
<style>
|
||||
body {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script src="libraries/p5.js"></script>
|
||||
<script src="libraries/p5.sound.min.js"></script>
|
||||
|
||||
<script src="sorts/selection.js"></script>
|
||||
<script src="sorts/bubble.js"></script>
|
||||
<script src="sorts/quick.js"></script>
|
||||
<script src="sorts/heap.js"></script>
|
||||
<script src="sorts/merge.js"></script>
|
||||
|
||||
<script src="sketch.js"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
3
Sorting Visualizer/libraries/p5.sound.min.js
vendored
3
Sorting Visualizer/libraries/p5.sound.min.js
vendored
File diff suppressed because one or more lines are too long
Binary file not shown.
Before Width: | Height: | Size: 22 MiB |
@ -1,148 +0,0 @@
|
||||
var arr=[];
|
||||
var size;
|
||||
var gap;
|
||||
var bar_width;
|
||||
var curr_sort=0;
|
||||
|
||||
function setup_init(s)
|
||||
{
|
||||
size=s;
|
||||
gap=5;
|
||||
bar_width=width/size-6;
|
||||
for(let i=0;i<size;i++)
|
||||
arr.push(random(20,height-30));
|
||||
}
|
||||
|
||||
function setup()
|
||||
{
|
||||
createCanvas(windowWidth,windowHeight);
|
||||
|
||||
if(width<500)
|
||||
setup_init(30);
|
||||
else
|
||||
setup_init(50);
|
||||
|
||||
|
||||
b1=createButton("RESET");
|
||||
b1.position(150,35);
|
||||
b1.mouseClicked(reset);
|
||||
|
||||
s1=createSlider(1,60,25,1);
|
||||
s1.position(70,6);
|
||||
|
||||
sel=createSelect();
|
||||
sel.position(10,35);
|
||||
sel.option("SELECTION SORT");
|
||||
sel.option("BUBBLE SORT");
|
||||
sel.option("QUICK SORT");
|
||||
sel.option("HEAP SORT");
|
||||
sel.option("MERGE SORT");
|
||||
sel.changed(changeSort);
|
||||
}
|
||||
|
||||
function windowResized()
|
||||
{
|
||||
resizeCanvas(windowWidth, windowHeight);
|
||||
if(width<500)
|
||||
setup_init(30);
|
||||
else
|
||||
setup_init(50);
|
||||
reset();
|
||||
}
|
||||
|
||||
function reset()
|
||||
{
|
||||
ss=0;
|
||||
bs=0;
|
||||
qs=0;
|
||||
hs=0;
|
||||
ms=0;
|
||||
arr=[];
|
||||
sorted_by_qs=[];
|
||||
for(let i=0;i<size;i++)
|
||||
arr.push(random(20,height-30));
|
||||
}
|
||||
|
||||
function changeSort()
|
||||
{
|
||||
if(sel.value()=="SELECTION SORT")
|
||||
curr_sort=0;
|
||||
else if(sel.value()=="BUBBLE SORT")
|
||||
curr_sort=1;
|
||||
else if(sel.value()=="QUICK SORT")
|
||||
curr_sort=2;
|
||||
else if(sel.value()=="HEAP SORT")
|
||||
curr_sort=3;
|
||||
else if(sel.value()=="MERGE SORT")
|
||||
curr_sort=4;
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
function draw()
|
||||
{
|
||||
background(color('#120136'));
|
||||
fill(255,100,100);
|
||||
stroke(255,100,100);
|
||||
text("SPEED",15,20);
|
||||
frameRate(s1.value());
|
||||
switch(curr_sort)
|
||||
{
|
||||
case(0):
|
||||
{
|
||||
ss_show();
|
||||
if(ss==0)
|
||||
{
|
||||
ss=1;
|
||||
ss_init();
|
||||
}
|
||||
ss_step();
|
||||
break;
|
||||
}
|
||||
case(1):
|
||||
{
|
||||
bs_show();
|
||||
if(bs==0)
|
||||
{
|
||||
bs=1;
|
||||
bs_init();
|
||||
}
|
||||
bs_step();
|
||||
break;
|
||||
}
|
||||
case(2):
|
||||
{
|
||||
if(qs==0)
|
||||
{
|
||||
qs=1;
|
||||
qs_init();
|
||||
}
|
||||
qs_show();
|
||||
qs_step();
|
||||
break;
|
||||
}
|
||||
case(3):
|
||||
{
|
||||
if(hs==0)
|
||||
{
|
||||
hs=1;
|
||||
hs_init();
|
||||
}
|
||||
hs_show();
|
||||
hs_step();
|
||||
break;
|
||||
}
|
||||
case(4):
|
||||
{
|
||||
if(ms==0)
|
||||
{
|
||||
ms=1;
|
||||
ms_init();
|
||||
}
|
||||
ms_show();
|
||||
ms_step();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
var bs=0;
|
||||
|
||||
function bs_init()
|
||||
{
|
||||
ii=0;
|
||||
jj=0;
|
||||
}
|
||||
|
||||
function bs_step() //what happens at each step
|
||||
{
|
||||
if(ii<size+1)
|
||||
{
|
||||
if(arr[jj+1]<arr[jj])
|
||||
{
|
||||
let t=arr[jj+1];
|
||||
arr[jj+1]=arr[jj];
|
||||
arr[jj]=t;
|
||||
}
|
||||
|
||||
jj++;
|
||||
|
||||
if(jj==size-ii)
|
||||
{
|
||||
jj=0;
|
||||
ii++;
|
||||
}
|
||||
|
||||
}
|
||||
if(ii==size)
|
||||
{
|
||||
ii++;
|
||||
jj--;
|
||||
}
|
||||
}
|
||||
|
||||
function bs_show()
|
||||
{
|
||||
stroke(255,0,0);
|
||||
strokeWeight(1);
|
||||
fill(100,50,255);
|
||||
for(let i=0;i<size;i++)
|
||||
{
|
||||
if(i==jj)
|
||||
{
|
||||
fill(color('#fcbf1e'));
|
||||
stroke(color('#fcbf1e'));
|
||||
}
|
||||
else if(i==(size-ii))
|
||||
{
|
||||
fill(color('#d92027'));
|
||||
stroke(color('#d92027'));
|
||||
}
|
||||
else
|
||||
{
|
||||
fill(color('#035aa6'));
|
||||
stroke(color('#035aa6'));
|
||||
}
|
||||
|
||||
rect(15+i*(bar_width+gap),height-arr[i],bar_width,arr[i],10);
|
||||
}
|
||||
|
||||
}
|
@ -1,135 +0,0 @@
|
||||
var downing,mainheapify,hsmax,whathsdo;
|
||||
var hs=0;
|
||||
|
||||
function hs_init()
|
||||
{
|
||||
downing=0;
|
||||
mainheapify=size;
|
||||
hsmax=size;
|
||||
whathsdo=0;
|
||||
}
|
||||
|
||||
function hs_step() //what happens at each step
|
||||
{
|
||||
if(whathsdo==0) //heapify
|
||||
{
|
||||
if(downing==0)
|
||||
{
|
||||
downing=1;
|
||||
mainheapify--;
|
||||
heapify=mainheapify;
|
||||
hs_down_step(heapify,size);
|
||||
}
|
||||
else
|
||||
{
|
||||
hs_down_step(heapify,size);
|
||||
}
|
||||
}
|
||||
else if(whathsdo==1) //after heapify, remove root, replace with last, flow-down for root
|
||||
{
|
||||
if(downing==0) // checking if in between flow-down
|
||||
{
|
||||
downing=1;
|
||||
hsmax--;
|
||||
let temp=arr[hsmax];
|
||||
arr[hsmax]=arr[0];
|
||||
arr[0]=temp;
|
||||
heapify=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
hs_down_step(heapify,hsmax);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function hs_down_step(h,newsize) // used in heapify and deletion of root of max-heap aka.flow-down
|
||||
{
|
||||
let lc=h*2+1;
|
||||
let rc=lc+1;
|
||||
let si=-1;
|
||||
if(rc<newsize)
|
||||
{
|
||||
if(arr[rc]>arr[lc])
|
||||
si=rc;
|
||||
else
|
||||
si=lc;
|
||||
}
|
||||
else if(lc<newsize)
|
||||
{
|
||||
si=lc;
|
||||
}
|
||||
else
|
||||
{
|
||||
downing=0;
|
||||
if(whathsdo==0)
|
||||
{
|
||||
if(mainheapify==0)
|
||||
whathsdo=1;
|
||||
}
|
||||
else if(whathsdo==1)
|
||||
{
|
||||
if(hsmax==0)
|
||||
whathsdo=2;
|
||||
}
|
||||
}
|
||||
if(si!=-1)
|
||||
{
|
||||
if(arr[si]>arr[h])
|
||||
{
|
||||
let temp=arr[si];
|
||||
arr[si]=arr[h];
|
||||
arr[h]=temp;
|
||||
heapify=si;
|
||||
}
|
||||
else
|
||||
{
|
||||
downing=0;
|
||||
if(whathsdo==0)
|
||||
if(mainheapify==0)
|
||||
whathsdo=1;
|
||||
else if(whathsdo==1)
|
||||
if(hsmax==0)
|
||||
whathsdo=2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function hs_show()
|
||||
{
|
||||
stroke(255,0,0);
|
||||
strokeWeight(1);
|
||||
fill(100,50,255);
|
||||
for(let i=0;i<size;i++)
|
||||
{
|
||||
if(whathsdo==0)
|
||||
{
|
||||
fill(color('#035aa6'));
|
||||
stroke(color('#035aa6'));
|
||||
}
|
||||
else
|
||||
{
|
||||
if(i<hsmax)
|
||||
{
|
||||
if(downing==0)
|
||||
{
|
||||
fill(color('#d92027'));
|
||||
stroke(color('#d92027'));
|
||||
}
|
||||
else
|
||||
{
|
||||
fill(color('#fcbf1e'));
|
||||
stroke(color('#fcbf1e'));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fill(color('#035aa6'));
|
||||
stroke(color('#035aa6'));
|
||||
}
|
||||
}
|
||||
rect(15+i*(bar_width+gap),height-arr[i],bar_width,arr[i],10);
|
||||
}
|
||||
fill(255);
|
||||
}
|
||||
|
@ -1,176 +0,0 @@
|
||||
|
||||
|
||||
var ms=0;
|
||||
var lptr,rptr,lend,rend;
|
||||
var pma=[];
|
||||
var sopma,wipma;
|
||||
var tosort=[];
|
||||
var sorted=[];
|
||||
var tomerge=[];
|
||||
var whatmsdo,startingmerge,phase2;
|
||||
|
||||
/*
|
||||
This one was tricky. Mainly because, recursion can not be used as every step during the sort has to be shown on screen.
|
||||
Hence I used 3 stacks TOSORT, SORTED, TOMERGE. Pop the first range ie: 0->len-1 from tosort.
|
||||
push back 2nd half of range followed by 1st half of range. for example, pop 0-9, push 5-9, push 0,4.
|
||||
Lets call this the break step. After each break step, push 0,mid,end into TOMERGE.
|
||||
Initially, this step happens recursively until range contains only 1 element. If range contains only 1 number, push that to sorted array.
|
||||
Now, if the SORTED stack contains 2 or more ranges, and the TOMERGE stack contains these two ranges at the top of the stack,
|
||||
then pop from merge, pop from sorted, and merge the range and replace the merged values in the original array.
|
||||
*/
|
||||
|
||||
function ms_init()
|
||||
{
|
||||
tosort=[];
|
||||
sorted=[];
|
||||
tomerge=[];
|
||||
tosort.push([0,size-1]);
|
||||
whatmsdo=0;
|
||||
startingmerge=0;
|
||||
lptr=-1;
|
||||
rptr=-1;
|
||||
lend=-1;
|
||||
rend=-1;
|
||||
pma=[];//partly merged array
|
||||
sopma=-1;//expected size of merged array
|
||||
wipma=-1;//where in partly merged array
|
||||
phase2=0;
|
||||
}
|
||||
|
||||
function ms_step() //what happens at each step
|
||||
{
|
||||
if(whatmsdo==0)
|
||||
{
|
||||
if(tomerge.length>0)
|
||||
{
|
||||
if(sorted.length>1)
|
||||
{
|
||||
let l=tomerge[tomerge.length-1][0];
|
||||
let r=tomerge[tomerge.length-1][2];
|
||||
let mid=tomerge[tomerge.length-1][1];
|
||||
if(sorted[sorted.length-1][0]==mid && sorted[sorted.length-1][1]==r && sorted[sorted.length-2][0]==l && sorted[sorted.length-2][1]==mid-1)
|
||||
{
|
||||
sorted.pop();
|
||||
sorted.pop();
|
||||
whatmsdo=1;
|
||||
startingmerge=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(whatmsdo==0 && tosort.length>0)
|
||||
{
|
||||
let curset=tosort.pop();
|
||||
let l=curset[0];
|
||||
let r=curset[1];
|
||||
if(l!=r)
|
||||
{
|
||||
let mid=int((l+r)/2);
|
||||
tosort.push([mid+1,r]);
|
||||
tosort.push([l,mid]);
|
||||
tomerge.push([l,mid+1,r]);
|
||||
}
|
||||
else
|
||||
sorted.push([l,l]);
|
||||
}
|
||||
}
|
||||
else if(whatmsdo==1)
|
||||
{
|
||||
if(startingmerge==1) //before starting the merge of two ranges
|
||||
{
|
||||
let merblo=tomerge.pop();
|
||||
lptr=merblo[0];
|
||||
rptr=merblo[1];
|
||||
lend=merblo[1]-1;
|
||||
rend=merblo[2];
|
||||
startingmerge=0;
|
||||
sopma=rend-lptr+1;
|
||||
}
|
||||
else // in between merge
|
||||
{
|
||||
if(pma.length==sopma)
|
||||
{
|
||||
for(let i=0;i<sopma;i++)
|
||||
arr[i+rend-sopma+1]=pma[i];
|
||||
pma=[];
|
||||
startingmerge=1;
|
||||
whatmsdo=0;
|
||||
phase2=0;
|
||||
sorted.push([rend-sopma+1,rend]);
|
||||
wipma=-1;
|
||||
if(sopma==size)
|
||||
whatmsdo=2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(phase2==0 && (lptr>lend || rptr>rend))
|
||||
{
|
||||
if(lptr>lend)
|
||||
{
|
||||
lptr=rptr;
|
||||
lend=rend;
|
||||
}
|
||||
phase2=1;
|
||||
}
|
||||
if(phase2==0)
|
||||
{
|
||||
if(arr[lptr]<arr[rptr])
|
||||
pma[++wipma]=arr[lptr++];
|
||||
else
|
||||
pma[++wipma]=arr[rptr++];
|
||||
}
|
||||
else if(phase2==1)
|
||||
{
|
||||
pma[++wipma]=arr[lptr++];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function ms_show()
|
||||
{
|
||||
stroke(255,0,0);
|
||||
strokeWeight(1);
|
||||
fill(100,50,255);
|
||||
for(let i=0;i<size;i++)
|
||||
{
|
||||
if(whatmsdo==1)
|
||||
{
|
||||
if(i<=rend && i>=rend-sopma+1)
|
||||
{
|
||||
stroke(color('#d92027'));
|
||||
fill(color('#d92027'));
|
||||
}
|
||||
else
|
||||
{
|
||||
stroke(color('#035aa6'));
|
||||
fill(color('#035aa6'));
|
||||
}
|
||||
}
|
||||
else if(whatmsdo==2)
|
||||
{
|
||||
stroke(color('#d92027'));
|
||||
fill(color('#d92027'));
|
||||
}
|
||||
else
|
||||
{
|
||||
stroke(color('#035aa6'));
|
||||
fill(color('#035aa6'));
|
||||
}
|
||||
rect(15+i*(bar_width+gap),height-arr[i],bar_width,arr[i],10);
|
||||
}
|
||||
if(whatmsdo==1)
|
||||
{
|
||||
for(let i=0;i<pma.length;i++)
|
||||
{
|
||||
stroke(color('#fcbf1e'));
|
||||
fill(color('#fcbf1e'));
|
||||
let tempi=i+rend-sopma+1;
|
||||
rect(15+tempi*(bar_width+gap),height-pma[i],bar_width/2,pma[i],10);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,105 +0,0 @@
|
||||
var qs=0;
|
||||
var qs_stack=[];
|
||||
var whatqsdo=0;
|
||||
var fast,slow;
|
||||
var sorted_by_qs=[];
|
||||
|
||||
function qs_init()
|
||||
{
|
||||
qs_stack=[];
|
||||
qs_stack.push([0,size-1]);
|
||||
whatqsdo=0;
|
||||
ii=0;
|
||||
jj=0;
|
||||
fast=0;
|
||||
slow=0;
|
||||
}
|
||||
|
||||
function qs_step() //what happens at each step
|
||||
{
|
||||
if(whatqsdo==0) //pop the next range to be sorted and set the pivot to the first element in the range
|
||||
{
|
||||
if(qs_stack.length>0)
|
||||
{
|
||||
let p=qs_stack.pop();
|
||||
ii=p[0];
|
||||
jj=p[1];
|
||||
fast=ii;
|
||||
slow=ii;
|
||||
whatqsdo=1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ii=-1;
|
||||
jj=-1;
|
||||
fast=-1;
|
||||
slow=-1;
|
||||
}
|
||||
}
|
||||
if(whatqsdo==1) //partitioning the array into <pivot and >pivot
|
||||
{
|
||||
if(arr[fast]<arr[ii])
|
||||
{
|
||||
slow++;
|
||||
let temp=arr[slow];
|
||||
arr[slow]=arr[fast];
|
||||
arr[fast]=temp;
|
||||
}
|
||||
fast++;
|
||||
if(fast==jj+1)
|
||||
{
|
||||
let temp=arr[ii];
|
||||
arr[ii]=arr[slow];
|
||||
arr[slow]=temp;
|
||||
sorted_by_qs.push(slow);
|
||||
whatqsdo=0;
|
||||
if(slow+1<=jj)
|
||||
qs_stack.push([slow+1,jj]);
|
||||
/* once pivot is in place pop right and left ranges to stack for sorting */
|
||||
if(ii<=slow-1)
|
||||
qs_stack.push([ii,slow-1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function qs_show()
|
||||
{
|
||||
stroke(255,0,0);
|
||||
strokeWeight(1);
|
||||
fill(100,50,255);
|
||||
for(let i=0;i<size;i++)
|
||||
{
|
||||
if(sorted_by_qs.includes(i))
|
||||
{
|
||||
fill(color('#fcbf1e'));
|
||||
stroke(color('#fcbf1e'));
|
||||
}
|
||||
else if(i==jj)
|
||||
{
|
||||
fill(color('#d92027'));
|
||||
stroke(color('#d92027'));
|
||||
}
|
||||
else if(i==ii)
|
||||
{
|
||||
fill(color('#d92027'));
|
||||
stroke(color('#d92027'));
|
||||
}
|
||||
else if(i==fast)
|
||||
{
|
||||
fill(color('#40bad5'));
|
||||
stroke(color('#40bad5'));
|
||||
}
|
||||
else
|
||||
{
|
||||
fill(color('#035aa6'));
|
||||
stroke(color('#035aa6'));
|
||||
}
|
||||
|
||||
rect(15+i*(bar_width+gap),height-arr[i],bar_width,arr[i],10);
|
||||
}
|
||||
stroke(255);
|
||||
strokeWeight(0.3);
|
||||
line(0,height-arr[ii],width,height-arr[ii]);
|
||||
if(slow>=0)
|
||||
line(18+slow*(bar_width+gap)+bar_width,0,18+slow*(bar_width+gap)+bar_width,height);
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
var ii;
|
||||
var jj;
|
||||
var smallii;
|
||||
// variables common to selection sort and bubble sort
|
||||
|
||||
var ss=0;
|
||||
|
||||
function ss_init()
|
||||
{
|
||||
ii=0;
|
||||
jj=0;
|
||||
smallii=0;
|
||||
}
|
||||
|
||||
function ss_step() //what happens at each step
|
||||
{
|
||||
if(ii<size)
|
||||
{
|
||||
if(arr[jj]<arr[smallii])
|
||||
{
|
||||
smallii=jj;
|
||||
}
|
||||
|
||||
if(jj==size)
|
||||
{
|
||||
let temp=arr[smallii];
|
||||
arr[smallii]=arr[ii];
|
||||
arr[ii]=temp;
|
||||
ii++;
|
||||
jj=ii;
|
||||
smallii=jj;
|
||||
}
|
||||
jj++;
|
||||
}
|
||||
}
|
||||
|
||||
function ss_show()
|
||||
{
|
||||
stroke(255,0,0);
|
||||
strokeWeight(1);
|
||||
fill(100,50,255);
|
||||
for(let i=0;i<size;i++)
|
||||
{
|
||||
if(i==jj)
|
||||
{
|
||||
stroke(color('#40bad5'));
|
||||
fill(color('#40bad5'));
|
||||
}
|
||||
else if(i==ii)
|
||||
{
|
||||
stroke(color('#d92027'));
|
||||
fill(color('#d92027'));
|
||||
}
|
||||
else if(i==smallii)
|
||||
{
|
||||
stroke(color('#35d0ba'));
|
||||
fill(color('#35d0ba'));
|
||||
}
|
||||
else
|
||||
{
|
||||
stroke(color('#035aa6'));
|
||||
fill(color('#035aa6'));
|
||||
}
|
||||
rect(15+i*(bar_width+gap),height-arr[i],bar_width,arr[i],10);
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user