选择排序可视化
Posted alittlecomputer
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了选择排序可视化相关的知识,希望对你有一定的参考价值。
选择排序(Selection sort)
选择排序是现在一系列数组中找到最小的,放到数组的第一个位置,然后选择第二小的,放到第二个位置。
如果未排序的数组为a,第一轮是先比较a[0]和a[1]的大小,如果a[0]>a[1],那么两个交换,否则不交换。这样得到的是a[0]是较小的那一个数。
然后把a[0]和a[2]进行比较,如果a[0]>a[2],那么两个交换,否则不交换。这样得到的是a[0]是较小的那一个数。
一直到a[0]和最后一个数比较,得到较小的数放在a[0]的位置。
这是第一轮。
第二轮是从a[1]开始和剩余的数比较,得到较小的数。这样一直循环,知道最后两个数。
可视化代码如下:
主文件:
index.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>选择排序算法动画</title> </head> <body style="height: 100%, width: 1000px;"> <canvas id="canvas" style="height: 100%"> 当前浏览器不支持Canvas,请更换浏览器后再试 </canvas> <script src="js/AlgoVisHelper.js"></script> <script src="js/AlgoFrame.js"></script> <script src="js/SelectionSortData.js"></script> <script src="js/AlgoVisualizer.js"></script> <script type="text/javascript"> window.onload = function(){ var sceneWidth = 1000; var sceneHeight = 600; var canvas = document.getElementById(\'canvas\'); var g2d = canvas.getContext(\'2d\'); canvas.width = sceneWidth; canvas.height = sceneHeight; var N = 100; var visualizer = new AlgoVisualizer(g2d, sceneWidth, sceneHeight, 100); } </script> </body> </html>
js文件:
AlgoFrame.js
class AlgoFrame{ constructor(g2d, title, canvasWidth, canvasHeight) { this.g2d = g2d; this.canvasWidth = canvasWidth; this.canvasHeight = canvasHeight; } getCanvasWidth() { return this.canvasWidth; } getCanvasHeight() { return this.canvasHeight; } repaint(){ // 具体绘制 this.g2d.clearRect(0, 0, this.canvasWidth, this.canvasHeight); var w = this.canvasWidth / this.data.N(); for (var i = 0; i < this.data.N(); i++) { if(i < this.data.orderedIndex){ AlgoVisHelper.setColor(this.g2d, AlgoVisHelper.Red); }else{ AlgoVisHelper.setColor(this.g2d, AlgoVisHelper.Grey); } if(i == this.data.currentCompareIndex){ AlgoVisHelper.setColor(this.g2d, AlgoVisHelper.LightBlue); } if(i == this.data.currentMinIndex){ AlgoVisHelper.setColor(this.g2d, AlgoVisHelper.Indigo); } AlgoVisHelper.fillRectangle(this.g2d, i * w, this.canvasHeight - this.data.get(i), w - 1, this.data.get(i)); } } render(data) { this.data = data; this.repaint(); } }
AlgoVisHelper.js
class AlgoVisHelper{
// 构造函数
constructor() {}
static fillRectangle(g2d, x, y, w, h){
g2d.fillRect(x, y, w, h);
}
static setColor(g2d, color){
g2d.fillStyle = color;
}
}
// 类中的静态属性
AlgoVisHelper.Red = "#F44336";
AlgoVisHelper.Pink = "#E91E63";
AlgoVisHelper.Purple = "#9C27B0";
AlgoVisHelper.DeepPurple = "#673AB7";
AlgoVisHelper.Indigo = "#3F51B5";
AlgoVisHelper.Blue = "#2196F3";
AlgoVisHelper.LightBlue = "#03A9F4";
AlgoVisHelper.Cyan = "#00BCD4";
AlgoVisHelper.Teal = "#009688";
AlgoVisHelper.Green = "#4CAF50";
AlgoVisHelper.LightGreen = "#8BC34A";
AlgoVisHelper.Lime = "#CDDC39";
AlgoVisHelper.Yellow = "#FFEB3B";
AlgoVisHelper.Amber = "#FFC107";
AlgoVisHelper.Orange = "#FF9800";
AlgoVisHelper.DeepOrange = "#FF5722";
AlgoVisHelper.Brown = "#795548";
AlgoVisHelper.Grey = "#9E9E9E";
AlgoVisHelper.BlueGrey = "#607D8B";
AlgoVisHelper.Black = "#000000";
AlgoVisHelper.White = "#FFFFFF";
AlgoVisualizer.js
class AlgoVisualizer { constructor(g2d, sceneWidth, sceneHeight, N) { // 动画的执行速度[毫秒] this.DELAY = 5; this.g2d = g2d; // 初始化数据 this.data = new SelectionSortData(N, sceneHeight); // 动画整个存储 this.data_list = new Array(); // 初始化视图 this.frame = new AlgoFrame(g2d, "Selection Sort Visualization", sceneWidth, sceneHeight); this.run(); } // 生成数据逻辑 run() { this.setData(0, -1, -1); for (var i = 0; i < this.data.N(); i++) { // 寻找[i, n) 区间里的最小值的索引 // [0,1) 前闭后开 0 <= n < 1 var minIndex = i; this.setData(i, -1, minIndex); for (var j = i + 1; j < this.data.N(); j++) { this.setData(i, j, minIndex); if (this.data.get(j) < this.data.get(minIndex)) { minIndex = j; this.setData(i, j, minIndex); } } this.data.swap(i, minIndex); this.setData(i + 1, -1, -1); } this.setData(this.data.N(), -1, -1); // 渲染数据 this.render(); } setData(orderedIndex, currentCompareIndex, currentMinIndex) { var data = new SelectionSortData(); data.orderedIndex = orderedIndex; data.currentCompareIndex = currentCompareIndex; data.currentMinIndex = currentMinIndex; data.numbers = this.data.numbers.slice(); this.data_list[this.data_list.length] = data } render(){ var i = 0; setInterval(() => { if(i < this.data_list.length){ this.frame.render(this.data_list[i]); i++; } }, this.DELAY); } }
SelectionSortData.js
class SelectionSortData{ constructor(N, randomBound){ this.numbers = new Array(N); this.orderedIndex = -1; // [0...orderedIndex) 是有序的 this.currentCompareIndex = -1; // 当前正在比较的元素索引 this.currentMinIndex = -1; // 当前找到的最小元素的索引 for( var i = 0 ; i < N ; i ++){ this.numbers[i] = parseInt((Math.random()*randomBound)) + 1; } } N(){ return this.numbers.length; } get(index){ if( index < 0 || index >= this.numbers.length){ throw ReferenceError("Invalid index to access Sort Data."); } return this.numbers[index]; } swap(i, j) { if( i < 0 || i >= this.numbers.length || j < 0 || j >= this.numbers.length){ throw ReferenceError("Invalid index to access Sort Data."); } var t = this.numbers[i]; this.numbers[i] = this.numbers[j]; this.numbers[j] = t; } }
文件结构如图所示:
js文件夹:
可视化过程如图所示:
以上是关于选择排序可视化的主要内容,如果未能解决你的问题,请参考以下文章