From d703ee951730a81c22bc875b416adbbd76367091 Mon Sep 17 00:00:00 2001 From: Chris Xiong Date: Wed, 28 Jun 2017 16:10:03 +0800 Subject: Initial commit. --- main.js | 729 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 729 insertions(+) create mode 100644 main.js (limited to 'main.js') diff --git a/main.js b/main.js new file mode 100644 index 0000000..09af115 --- /dev/null +++ b/main.js @@ -0,0 +1,729 @@ +//License: Expat(MIT) +//Chris Xiong 2017 +const mrkcol=["#FFF","#F00","#0F0","#00F","#0FF","#F0F","#FF0","#F80","#F08","#0F8","#8F0","#80F","#08F"]; +const ui={}; +function min(a,b){return ab?a:b;} +async function sleep(ms) +{ + return new Promise(resolve=>setTimeout(resolve,ms)); +} +class ISort +{ + constructor(h) + { + this.executing=false; + this.finished=false; + this.step=false; + this.h=h; + } + options() + { + return ""; + } + async wait() + { + do{await sleep(5);}while(!this.step); + this.step=false; + } + async execute(){} +}; +class BubbleSort extends ISort +{ + constructor(h){super(h);} + async execute() + { + this.executing=true; + const h=this.h; + let c=h.count; + let swapped=false; + do + { + swapped=false; + for(let i=1;i=0&&h.get(j)>t;--j) + { + h.mark(j,2); + h.swap(j,j+1); + await this.wait(); + h.mark(j,0); + } + h.mark(i,0); + } + this.finished=true; + } +} +class CombSort extends ISort +{ + constructor(h){super(h);} + async execute() + { + this.executing=true; + const h=this.h; + let swapped=false; + let gap=h.count; + while((gap>1)||swapped) + { + if(gap>1)gap=Math.floor(gap/1.3); + swapped=false; + for(let i=0;gap+ih.get(i+gap)) + { + h.swap(i,i+gap); + swapped=true; + } + await this.wait(); + h.mark(i,0);h.mark(i+gap,0); + } + } + this.finished=true; + } +} +class ShellSort extends ISort +{ + constructor(h){super(h);} + async execute() + { + this.executing=true; + const gaps=[1073790977,268460033,67121153,16783361,4197377, + 1050113,262913,65921,16577,4193,1073,281,77,23,8,1]; + for(let g=0;g=cg&&(tv=h.get(j-cg))>t;j-=cg) + { + let om=h.getmark(j); + h.mark(j,1); + h.set(j,tv); + await this.wait(); + h.mark(j,om); + } + h.set(j,t); + await this.wait(); + h.mark(i,0); + } + this.finished=true; + } +} +class ShakerSort extends ISort +{ + constructor(h){super(h);} + async execute() + { + this.executing=true; + const h=this.h; + for(let L=0,R=h.count-1,m=0;LL;--i) + { + h.mark(i-1,2);h.mark(i,1); + if(h.compar(i-1,i)>0) + { + h.swap(i-1,i); + m=i; + } + await this.wait(); + h.mark(i-1,0);h.mark(i,0); + } + L=m; + for(let i=L;i0) + { + h.swap(i+1,i); + m=i; + } + await this.wait(); + h.mark(i+1,0);h.mark(i,0); + } + R=m; + } + this.finished=true; + } +} +class QuickSort extends ISort +{ + constructor(h){super(h);} + options() + { + return `{ + "optionlist": + [ + { + "dispname":"Pivot Selection", + "opt":"pivot", + "type":"enumsingle", + "options":[ + "First", + "Last", + "Middle", + "Random" + ], + "defaultv":"2" + } + ] + }`; + } + async _sort(l,r) + { + const h=this.h; + let i=l,j=r; + let p=l; + switch(Number(h.getopt("pivot"))) + { + case 0: + break; + case 1: + p=r; + break; + case 2: + p=(l+r)>>1; + break; + case 3: + p=Math.floor(Math.random()*(r+1-l))+l; + break; + } + let x=h.get(p); + h.mark(p,3); + do + { + while(h.comparv(h.get(i),x)==-1) + { + ++i;h.mark(i,1); + await this.wait();h.mark(i,0); + } + while(h.comparv(h.get(j),x)== 1) + { + --j;h.mark(j,1); + await this.wait();h.mark(j,0); + } + if(i<=j){h.swap(i,j);++i;--j;} + h.mark(i,1);h.mark(j,1); + await this.wait(); + h.mark(i,0);h.mark(j,0); + h.mark(p,3); + } + while(i<=j); + h.mark(p,0); + if(l=R)return; + const M=(L+R)>>1; + await this._sort(L,M); + await this._sort(M,R); + await this.merge(L,R,M); + } + async execute() + { + this.executing=true; + await this._sort(0,this.h.count); + this.finished=true; + } +} +class HeapSort extends ISort +{ + constructor(h){super(h);} + async execute() + { + this.executing=true; + const h=this.h; + let n=h.count,le=n>>1; + for(let i=le;i0)--le; + else + { + if(!--n)break; + h.swap(0,n); + h.mark(n,1); + if(n+10)++ch; + if(h.compar(ch,par)>0) + { + h.swap(ch,par); + par=ch;ch=(par<<1)|1; + }else break; + await this.wait(); + } + h.mark(le,Math.floor(Math.log(le+1)/Math.log(2))+2); + await this.wait(); + } + this.finished=true; + } +} +class LSDRadixSort extends ISort +{ + constructor(h){super(h);} + async execute() + { + this.executing=true; + const R=4; + const pm=Math.ceil(Math.log(h.maxval+1)/Math.log(R)); + for(let p=0;p=h.count)continue; + h.mark(ps[i],3); + } + for(let i=0;ii) + { + h.swap(L+i,L+j); + await this.wait(); + } + i+=c[Math.floor(h.get(L+i)/base)%Rdx]; + } + for(let i=0;ipm)return; + let s=L; + for(let i=0;i1) + await this._sort(s,s+c[i],dpt+1); + s+=c[i]; + } + } + async execute() + { + this.executing=true; + await this._sort(0,h.count,0); + this.finished=true; + } +} +class SortHypervisor +{ + constructor() + { + this.ctx=ui.cvs.getContext("2d"); + this.w=ui.cvs.width; + this.h=ui.cvs.height; + this.ctx.clearRect(0,0,this.w,this.h); + this.ctx.lineWidth=window.devicePixelRatio.toString(); + window.AudioContext=window.AudioContext||window.webkitAudioContext; + this.actx=new AudioContext(); + this.dly=20; + this.reset(100); + } + reset(c) + { + this.raccess=0; + this.waccess=0; + this.count=c; + this.bin=[]; + this.mrk=[]; + this.algo=null; + this.initalgo(); + this.breakexec=false; + for(let i=0;i0;--i) + { + let r=Math.floor(Math.random()*(i+1)); + let t=this.bin[i]; + this.bin[i]=this.bin[r]; + this.bin[r]=t; + } + + break; + } + this.fullredraw(); + } + swap(ida,idb) + { + this.raccess+=2; + this.waccess+=2; + let t=this.bin[ida]; + this.bin[ida]=this.bin[idb]; + this.bin[idb]=t; + this.singleredraw(ida); + this.singleredraw(idb); + } + get(id) + { + ++this.raccess; + this.sound(this.bin[id]/this.count*1100+132); + return this.bin[id]; + } + set(id,v) + { + ++this.waccess; + this.bin[id]=v; + this.sound(this.bin[id]/this.count*1100+132); + this.singleredraw(id); + } + comparv(a,b){return ab?1:0;} + compar(ida,idb) + { + let a=this.get(ida),b=this.get(idb); + return this.comparv(a,b); + } + getmark(id){return this.mrk[id];} + mark(id,m){ + this.mrk[id]=m; + this.singleredraw(id); + } + fullredraw() + { + const w=this.w,h=this.h,n=this.count; + this.ctx.clearRect(0,0,w,h); + for(let i=0;iwindow.innerWidth*0.95)ui.cvs.width=window.innerWidth*0.95; + ui.cvs.height=ui.cvs.width/16*9; + if(ui.cvs.height>window.innerHeight*0.72) + { + ui.cvs.height=window.innerHeight*0.72; + ui.cvs.width=ui.cvs.height/9*16; + } + ui.cvs.style.width=ui.cvs.width+"px"; + ui.cvs.style.height=ui.cvs.height+"px"; + ui.cvs.width=ui.cvs.width*window.devicePixelRatio; + ui.cvs.height=ui.cvs.height*window.devicePixelRatio; + ui.rspd.onchange=()=>{h.dly=Number(ui.rspd.value);} + ui.rcnt.onchange=()=>{h.reset(Number(ui.rcnt.value));h.fullredraw();} + ui.rspd.oninput=()=>{ui.lbspd.innerHTML=ui.rspd.value+"ms";} + ui.rcnt.oninput=()=>{ui.lbcnt.innerHTML=ui.rcnt.value;} + ui.salg.onchange=()=>{h.changealgo();} + h=new SortHypervisor(); + h.fullredraw(); +} -- cgit v1.2.3