zoukankan      html  css  js  c++  java
  • 技术分享:基本排序算法

     前言:

     今天我给大家分享一点排序算法的知识。大概要花30分钟的时间,我尽量控制在20分钟左右。

    首先,我想问大家一个问题,你们知道的排序算法有哪些?冒泡排序?快速排序?

    那你们知道它们之间的差异是什么?有的快有的慢对吧?没错,排序算法分为基本排序算法和高级排序算法。我今天要讲的就是基本排序算法。请看下面的目录。

    技术主题:基本排序算法

    目录:

    一、冒泡排序

    1. 原理
    2. 实现方法

    二、选择排序

    1. 原理
    2. 实现方法

    三、插入排序

    1. 原理
    2. 实现方法

    四、如何通过测试来比较这三种算法的速度?

    五、其他(有时间的话就讲)

    【问题1】sort()方法用的是什么排序算法?

    【问题2】for循环中++i 和 i++ 的区别?

     基本排序算法有三种,冒泡排序、选择排序、插入排序。我会依次讲它们的原理和实现方法。最后会讲下如何比较它们的排序速度。

    冒泡排序

    我们先来看冒泡排序,冒泡排序是最基本的排序算法,也是最慢的。

    它的原理是什么呢?我用表格给大家演示。更直观。(打开表格,随机输入一串数据)

     从第一个数字开始,和它相邻的数字比较,左边比右边大就交换。一直重复这个过程,直到最大的数字移到最右端。

     不知道大家听懂了没有?有问题可以提出来哦。没问题的话,那我给大家看下代码怎么实现这种算法。看完代码我再给大家演示一遍也可以。

    function swap(arr, index1, index2) {
        var temp = arr[index1];
        arr[index1] = arr[index2];
        arr[index2] = temp;
    }
    
    
    /**冒泡排序 */
    function bubbleSort(arr) {
        for (var outer = arr.length; outer >= 2; --outer) {
            console.log(arr.toString());
            for (var inner = 0; inner <= outer - 1; ++inner) {
                if (arr[inner] > arr[inner+1]) {
                    swap(arr, inner, inner + 1);
                }
            }
        }
        console.log(arr.toString());
    }
    
    
    /**选择排序 */
    function selectionSort(arr) {
        var min;
        for (var outer = 0; outer < arr.length - 1; ++outer) {
            console.log(arr.toString());
            min = outer;
            for (var inner = outer + 1; inner < arr.length; ++inner) {
                if (arr[inner] < arr[min]) {
                    min = inner;
                }
            }
            swap(arr, outer, min);
        }
        console.log(arr.toString());
    }
    
    /**插入排序 */
    function insertionSort(arr) {
        var temp, inner;
        for (var outer = 1; outer <= arr.length - 1; ++outer) {
            console.log(arr.toString());
            temp = arr[outer];
            inner = outer;
            while(inner > 0 && (arr[inner-1] >= temp)) {
                arr[inner] = arr[inner - 1];
                --inner;
            }
            arr[inner] = temp;
        }
        console.log(arr.toString());
    }

    这里有3个函数。分别用来实现冒泡排序、选择排序、插入排序。

    我先讲一下他们的共同点,第一、都是嵌套循环,第二、都用到了交换函数swap,请看swap的代码。

    swap函数

    function swap(arr, index1, index2) {
        var temp = arr[index1];
        arr[index1] = arr[index2];
        arr[index2] = temp;
    }

    现在看下冒泡排序函数

    /**冒泡排序 */
    function bubbleSort(arr) {
        for (var outer = arr.length; outer >= 2; --outer) {
            console.log(arr.toString());
            for (var inner = 0; inner <= outer - 1; ++inner) {
                if (arr[inner] > arr[inner+1]) {
                    swap(arr, inner, inner + 1);
                }
            }
        }
        console.log(arr.toString());
    }

    外层的for循环是用来控制内层for循环的长度的。所以它是递减的。

    (。。。。)讲完后

    我再给大家用表格演示一遍冒泡排序的过程,一边对照代码一边演示

    现在用代码执行一遍,看看代码执行的冒泡排序和我演示的过程是不是一致的。执行结果如下:

    大家有什么问题吗?没有的话我继续讲选择排序。
    (时间有限,我得快点讲)

    选择排序

    请看表格。

     请看代码。

    /**选择排序 */
    function selectionSort(arr) {
        var min;
        for (var outer = 0; outer < arr.length - 1; ++outer) {
            console.log(arr.toString());
            min = outer;
            for (var inner = outer + 1; inner < arr.length; ++inner) {
                if (arr[inner] < arr[min]) {
                    min = inner;
                }
            }
            swap(arr, outer, min);
        }
        console.log(arr.toString());
    }

    同样也用代码验证一下[9, 2, 6, 3, 8, 0]

     有些循环输出的结果和上一次是一样的,我在表格中省略掉了。

    选择排序就是这样。大家有什么疑问吗?要不要我用表格再演示一遍。没有的话我继续讲插入排序。

    插入排序

    请看表格,还是这一组数据。

     看下插入排序的方法

    /**插入排序 */
    function insertionSort(arr) {
        var temp, inner;
        for (var outer = 1; outer <= arr.length - 1; ++outer) {
            console.log(arr.toString());
            temp = arr[outer];
            inner = outer;
            while(inner > 0 && (arr[inner-1] >= temp)) {
                arr[inner] = arr[inner - 1];
                --inner;
            }
            arr[inner] = temp;
        }
        console.log(arr.toString());
    }

    代码验证一下

    到这里三种基本排序算法都讲完了。

    你们都听懂了吗?我提个问题吧,你们觉得哪一种排序算法好?

    我们需要一个客观的衡量。

    这三种排序算法的复杂度非常相似。从理论上来说,他们的执行效率也应该差不多。现在我们就做一个测试来比较它们的效率,看看到底哪个更快。

    这个测试怎么来做呢?我们不可能手动输入1000,10000个数据来测试。所以,

    首先我们要准备2个工具。一个可以生成随机数组的类。还有一个问题是如何计时。这个等下再说。先看怎么生成数组。

    function CArray(numElements) {
        this.dataStore = [];
        this.pos = 0;
        this.numElements = numElements;
        this.toString = toString;
        this.setData = setData;
        this.swap = swap; // 交换方法
        this.bubbleSort = bubbleSort; // 冒泡排序
        this.selectionSort = selectionSort; // 选择排序
        this.insertionSort = insertionSort; // 插入排序
    
        for (var i = 0; i < numElements; ++i) {
            this.dataStore[i] = i;
        }
    }
    
    function setData() {
        for (var i = 0; i < this.numElements; ++i) {
            this.dataStore[i] = Math.floor(Math.random() * (this.numElements + 1)); // 这里为什么要+1?
        }
    }
    
    function toString() {
        var restr = '';
        for (var i = 0; i < this.dataStore.length; ++i) {
            restr += this.dataStore[i] + ' ';
            if (i > 0 & i % 10 == 0) {
                restr += '
    '
            }
        }
        return restr;
    }
    
    function swap(arr, index1, index2) {
        var temp = arr[index1];
        arr[index1] = arr[index2];
        arr[index2] = temp;
    }
    
    /**冒泡排序 */
    function bubbleSort() {
        var len = this.dataStore.length;
        for (var outer = len; outer >= 2; --outer) {
            for (var inner = 0; inner <= outer - 1; ++inner) {
                if (this.dataStore[inner] > this.dataStore[inner+1]) {
                    swap(this.dataStore, inner, inner + 1);
                }
            }
        }
    }
    
    /**选择排序 */
    function selectionSort() {
        var min;
        for (var outer = 0; outer <= this.dataStore.length - 2; ++outer) {
            min = outer;
            for (var inner = outer + 1; inner <= this.dataStore.length - 1; ++inner) {
                if (this.dataStore[inner] < this.dataStore[min]) {
                    min = inner;
                }
            }
            swap(this.dataStore, outer, min);
        }
    }
    
    /**插入排序 */
    function insertionSort() {
        var temp, inner;
        for (var outer = 1; outer <= this.dataStore.length - 1; ++outer) {
            temp = this.dataStore[outer];
            inner = outer;
            while(inner > 0 && (this.dataStore[inner-1] >= temp)) {
                this.dataStore[inner] = this.dataStore[inner - 1];
                --inner;
            }
            this.dataStore[inner] = temp;
        }
    }

    这里面的冒泡排序、选择排序和插入排序的三个方法和上面用的稍微有些区别,那就是不用传入数组,直接调用实例上的内置方法。其他都一样。

    我们先来生成一个长度100,值为0-100之间的数组。

    为了节省时间,这些代码我都提前准备好了。请看

    var numElements = 100;
    var nums = new CArray(numElements);
    nums.setData();
    console.log(nums.toString());

    结果如下:

    现在数据准备好了。我们来看计时怎么写?

    先给大家看一个小例子

    var start = new Date().getTime();
    for (var i = 1; i < 1000; ++i) {
        console.log(i);
    }
    var stop = new Date().getTime();
    var elapsed = stop - start;
    console.log('消耗的时间为:' + elapsed + ' 毫秒');

    运行一下就可以看到这个简单的for循环执行需要时间

    最后把这个计时方法用到排序算法测速上。

    var start = new Date().getTime();
    nums.bubbleSort();
    var stop = new Date().getTime();
    var elapsed = stop - start;
    console.log(numElements + ' 个元素执行【冒泡排序】消耗的时间为:' + elapsed + ' 毫秒');
    
    start = new Date().getTime();
    nums.selectionSort();
    stop = new Date().getTime();
    elapsed = stop - start;
    console.log(numElements + ' 个元素执行【选择排序】消耗的时间为:' + elapsed + ' 毫秒');
    
    start = new Date().getTime();
    nums.insertionSort();
    stop = new Date().getTime();
    elapsed = stop - start;
    console.log(numElements + ' 个元素执行【插入排序】消耗的时间为:' + elapsed + ' 毫秒');

    先看下100个数据三种排序算法的速度分别是多少?

    结果如下:

     差不多。

    再看1000个数据的情况,把numElements的值改成1000.

     差距已经出来了。再看看10000个数据如何?

     这个差距非常明显了。

    今天的主要内容就是这些。大家有什么疑问可以提出来。

    有时间的话,我想提个问题,你们知道sort()用的什么排序算法吗?

    【答】

    ECMAScript没有定义使用哪种排序算法,各个浏览器的实现方式会有不同。火狐中使用的是归并排序,Chrome使用的是插入排序和快速排序的结合排序算法。数组长度不超过10时,使用插入排序。超过10则用快速排序。因为在数组较短时插入排序更有效。

    今天的分享到此结束,谢谢大家!

  • 相关阅读:
    485串口接线
    mvc3 升级mvc5
    VB连接ACCESS数据库,使用 LIKE 通配符问题
    VB6 读写西门子PLC
    可用的 .net core 支持 RSA 私钥加密工具类
    解决 Win7 远程桌面 已停止工作的问题
    解决 WinForm 重写 CreateParams 隐藏窗口以后的显示问题
    解决安装 .net framework 发生 extracting files error 问题
    CentOS7 安装配置笔记
    通过特殊处理 Resize 事件解决 WinForm 加载时闪烁问题的一个方法
  • 原文地址:https://www.cnblogs.com/cathy1024/p/12996523.html
Copyright © 2011-2022 走看看