zoukankan      html  css  js  c++  java
  • 选择排序可视化

    选择排序(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%,  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文件夹:

     可视化过程如图所示:

  • 相关阅读:
    「模拟赛20180306」回忆树 memory LCA+KMP+AC自动机+树状数组
    python写一个通讯录
    Git学习笔记
    交换排序
    用Windows自带的方法创建WiFi
    MySQL之触发器
    插入排序
    range和arange的区别
    Spring前后端跨域请求设置
    三、图的定义及遍历
  • 原文地址:https://www.cnblogs.com/LoganChen/p/8836180.html
Copyright © 2011-2022 走看看