/* * バブルソートの可視化 *  現在比較・入れ替えしているもの = 赤 *  未ソートのもの = 青 *  ソート完了のもの = 水色 */ /* ---------------------------------------- * グローバル変数 * ---------------------------------------- */ // 共通 int n[] = new int[10]; // 初期値を特に決めていない配列 boolean mode_sorting = true; // sort(true)か swap(false)か。 int limit = 9; // 比較のために見に行く下の限界位置 // 比較(sort) int sort_i = 0; // 現在何番目の部分の比較をしているか boolean sort_flag = true; // 現在ソートをしているか(終わってないか) // 入れ替え(swap) int swapTime = 0; // 入れ替えに経過している時間(移動量に使用) /* ---------------------------------------- * 初期設定 * ---------------------------------------- */ void setup(){ size(400, 300); // 横400、縦300の新しいウィンドウ background(255); // 背景を白で塗りつぶす reset(n); // 初期値の設定 } // 初期状態にする void reset(int n[]){ sort_i = 0; // 一番上から比較をまた始める limit = 9; // 一番下まで見に行く swapTime = 0; mode_sorting = true; // 値をランダムに設定 int i; for(i=0; i<10; i++){ n[i] = int(random(5, 100)); } draw_plane(n, color(0, 0, 255)); // 画面の描画。すべて青 } /* ---------------------------------------- * 定期的な処理 * ---------------------------------------- */ // 画面を描き直す void draw() { // 比較(sort)をする if(mode_sorting){ delay(800); // 0.8秒プログラムを止める(目で追えるように) sort_draw(n); // 画面描画 sorting(); // 比較を行う } // 入れ替え(swap)をする else{ if(swapTime == 0){ // 入れ替えはじめる瞬間に delay(300); // 0.3秒プログラムを止める(目で追えるように) } swap_draw(); // 画面、入れ替えの様子を描画 swapping(); // 値の交換を行う } check(); // 一番下まで見に行ったかチェック } // 一番下まで見に行ったかチェック void check() { if(sort_i >= limit){ // 一番下まで比較したら if(sort_flag){ // ソートが終わっているかどうか draw_plane(n, color(0, 150, 255)); // 画面を書き直す noLoop(); // ソートができたからプログラムを止める } sort_i = 0; // また上からソートし直す sort_flag = true; // リセットのような役割 limit--; // 最後に見た棒は決定(もう入れ替えがおこらない) } } // 画面の描画(ソート開始時と終了時) void draw_plane(int n[], color c){ background(255); // 背景を真っ白に塗りつぶす // drawRectを10本分描く int i; for(i=0; i<10;i++){ drawRect(i, n[i], c); } } /* ---------------------------------------- * 比較(sort) * ---------------------------------------- */ // 画面描画 void sort_draw(int n[]){ background(255); // 背景を真っ白に塗りつぶす // drawRectを10本分描く int i; for(i=0; i<10;i++){ if(i == sort_i || i == sort_i + 1){ drawRect(i, n[i], color(255, 0, 0)); // 現在比較している2本 } else if(i > limit){ drawRect(i, n[i], color(0, 150, 255)); // ソート完了している棒 } else{ drawRect(i, n[i], color(0, 0, 255)); // 比較しているところ以外 } } } // 現在見ているところとすぐ下を比較する void sorting(){ int i = sort_i; int temp; if(n[i] > n[i+1]){ sort_flag = false; // 交換の必要があるということは、ソートが終わってない mode_sorting = false; // 次は入れ替える } else{ sort_i++; // ひとつ下へ } } /* ---------------------------------------- * 入れ替え(swap) * ---------------------------------------- */ void swap_draw(){ background(255); // 背景を真っ白に塗りつぶす swapTime++; // 移動量(入れ替え経過時間)を増やす // drawRectを10本分描く int i; for(i=0; i<10;i++){ if(i == sort_i){ fill(255, 0, 0); // 赤 rect(0, i*30 + swapTime ,n[i]*4,30); // 入れ替えのため、下にやや動いている棒 } else if(i == sort_i + 1){ fill(255, 0, 0); // 赤 rect(0, i*30 - swapTime ,n[i]*4,30); // 入れ替えのため、上にやや動いている棒 } else if(i > limit){ drawRect(i, n[i], color(0, 150, 255)); // ソート完了している棒 } else{ drawRect(i, n[i], color(0, 0, 255)); // その他の棒。青。 } } } // 実際に値を入れ替える void swapping() { if(swapTime >= 30){ // 画面上での入れ替えが終わったら swapTime = 0; // 入れ替え経過時間(移動量)をリセット mode_sorting = true; // 次は比較を行う // 値のswap int temp; int i = sort_i; temp = n[i]; n[i] = n[i+1]; n[i+1] = temp; sort_i++; // ひとつ下へ } } /* ---------------------------------------- * 汎用 * ---------------------------------------- */ // 棒を1本書く // 何番目か(位置)と値(長さ)と色を受け取る void drawRect(int position, int value, color c){ fill(c); // 引数として受け取った色で塗りつぶす rect(0, position*30 ,value*4,30); } /* ---------------------------------------- * 入力 * ---------------------------------------- */ // キーが押されたときの処理 void keyReleased(){ if(key == 's'){ reset(n); // 状態をリセットする loop(); // プログラムが停止していたら再開する } }