まず第一に、横たわっているすべての「睡眠」の質問 ( sleep() の JavaScript バージョンとは?など) を調べましたが、受け入れられる解決策が見つかりませんでした。
あらゆる種類のアルゴリズムの視覚的な教育ツールを作成したいと考えています。そのために、jQuery で JavaScript を使用してデータを表示し、きれいに塗りつぶしています。それを開始するために、並べ替えのサンプルを実行したいと思います。ここでは、配列が表示され、シャッフルされ、視覚的に楽しい方法で並べ替えられます。私が実現したいのは、2 つのセルが強調表示され (簡単)、交換される可能性があり (簡単)、次のペアがテストされる前にわずかな遅延がある (難しい) ことです。
JavaScriptには明示的な「スリープ」メソッドがないことを理解しています。ただし、setTimeout を使用するようにコードを再構築することは、すべてのアルゴリズムを再帰的に書き直すことを意味し、これは大きな障害になります (ただし、明らかに不可能ではありません)。
サンプル問題として、バブル ソートのサンプルを見てみましょう。
function bubble_sort(arr){
for(var i=0;i<arr.length;i++){
for(var j=1;j<arr.length;j++){
highlight(j-1);
highlight(j);
if(arr[j-1] > arr[j]){
visible_swap(arr, j, j-1);
}
sleep(1000);
}
}
exhibit_array(arr);
}
これは明らかに setTimeout で動作するように再帰的に書き直すことができますが、私が考えているすべてのアルゴリズムでそうするには、かなりの時間がかかります。何か不足していますか?実装をそのままにして、自由にスリープを配置する「簡単な」方法はありますか?
編集:私は2つの解決策を見つけました.きれいなものと互換性のあるものです. 残念ながら、きれいなものは Firefox でしか動作せず、素晴らしい yield セマンティクスを利用しています (ここにいくつかのサンプルの説明があります: https://developer.mozilla.org/en/New_in_JavaScript_1.7 )。これは実際に私の問題を完全に解決します。
function bubble_sort(arr){
for(var i=0;i<arr.length;i++){
for(var j=1;j<arr.length;j++){
highlight(j-1);
highlight(j);
if(arr[j-1] > arr[j]){
visible_swap(arr, j, j-1);
}
yield true;
}
}
yield false;
}
var bubble = bubble_sort(arr)
function gen(){
if(bubble.next()){
setTimeout(gen, 500);
}
else{
alert("Done!");
}
}
これは私にとっては素晴らしく機能しますが、現在 Firefox でのみサポートされている yield 機能に依存しています。これが機能するには、<script type="text/javascript;version=1.7"> を使用する必要があることに注意してください。しかし、これは完璧です。また、無限のアルゴリズムに対しても機能し、必要に応じてそれらが無駄に苦労していることを示していた可能性があります.
以下の回答に基づいて、私が見つけた2番目の解決策も同様に機能します。
function bubble_sort(arr){
var q = new Array();
for(var i=0;i<arr.length;i++){
for(var j=1;j<arr.length;j++){
q[q.length] = [ [highlight, j-1 ], [highlight, j] ];
if(arr[j-1] > arr[j]){
swap(arr, j, j-1);
q[q.length] = [ [visible_swap, j, j-1] ];
}
}
}
return q;
}
function play(q, step){
if(q.length == 0)
return;
clear_highlights();
cmds = q.shift();
for(ind in cmds){
cmd = cmds[ind];
f = cmd.shift();
f.apply(null, cmd);
}
setTimeout(function(){ play(q, step); }, step);
}
これも同様に機能します。これは構文的にかなり厄介ですが、すべてのブラウザーで確実にうまく機能します。
結局のところ、スリープのような構文を実装するjavascriptの「拡張機能」があるようです。これは明らかに上記のすべてよりも優れています。助けてくれてありがとう!