zoukankan      html  css  js  c++  java
  • 极简教程:数据结构与算法(一)

    2020-4-28

    这是一套关与数据结构与算法的系列文章,值得你持续关注

    时间复杂度与空间复杂度

    我尽量用 最少的文字,最少的代码。来讲明白数据结构与算法。
    

    1. 数据结构与算法是为了解决 “快” 和 “省”的问题

    2. 评估 “快” 和 “省”方法就是 “复杂度分析”

    3. “复杂度分析” 分为 “时间复杂度” 和 “空间复杂度”

    4. “时间复杂度” 指的是:代码执行时间 随着 数据规模 的增长变化趋势

    5. “空间复杂度” 指的是:存储空间 与 数据规模 的增长变化趋势

    6. 复杂度分析过程

    const findCat = (n) => {
        // 定义变量
        let name = '石兴龙';
        let animal = '猫';
        let cat_number = 0
        // n 越大,循环的次数越多
        for (let i = 0; i < n; i++) {
            cat_number++;
        }
        console.log(`${name} 有 ${cat_number} 只猫`)
    }
    findCat(1)     // 石兴龙 有 1 只猫
    findCat(10)    // 石兴龙 有 10 只猫
    findCat(n)     // 石兴龙 有 n 只猫
    

    先来看看执行过程。先定义了 3 个变量、其次 for 循环、最后一行打印。假设每一行的执行时间为 x 。那么总的执行时间为:

    T(n) = 3x + for(n) + x

    其中 3x 和 x 的执行时间是不会变的,和 n 没有关系,我们忽略不计。那么现在的执行时间是:

    T(n) = for(n) = O(n)

    find 函数的复杂度完全依赖变量 n 的大小,所以就是 O(n)

    7. 复杂度大概分为5种:

    | 复杂度 | 执行速度 |
    | -- | --|
    | O(1) | 最快 |
    | O(logn) | 快 |
    | O(n) | 慢 |
    | O(nLong) | 很慢 |
    | O(n次方) | 最慢 |
    
    // 最快的代码 O(1)
    let findCat = () => {
        let name = '石兴龙';
        let animal = '猫';
        let cat_number = 0
        let n = 10
        for (let i = 0; i < n; i++) {
            cat_number++;
        }
        console.log(`${name} 有 ${cat_number} 只猫`)
    }
    findCat() // 石兴龙 有 10 只猫 
    // 虽然也有 for 循环,但是执行时间是固定的
    
    // 快的代码 O(logn)
    findCat = (n) => {
        let name = '石兴龙';
        let animal = '猫';
        let cat_number = 0
        for (let i = 0; i < n; i++) {
            if (i % 2 === 0) {
                cat_number++;
            }
        }
        console.log(`${name} 有 ${cat_number} 只猫`)
    }
    findCat(10) // 石兴龙 有 5 只猫
    // logn 函数产生的值 < n
    
    // 慢的代码 O(n)
    findCat = (n) => {
        let name = '石兴龙';
        let animal = '猫';
        let cat_number = 0
        for (let i = 0; i < n; i++) {
            cat_number++;
        }
        console.log(`${name} 有 ${cat_number} 只猫`)
    }
    findCat(10) // 石兴龙 有 10 只猫
    // 执行的时间 和 n 成正比
    
    // 很慢的代码 O(nLong)
    findCat = (n) => {
        let name = '石兴龙';
        let animal = '猫';
        let cat_number = 0
        for (let i = 0; i < n;) {
            i += 0.5;
            cat_number += 1;
        }
        console.log(`${name} 有 ${cat_number} 只猫`)
    }
    findCat(10) // 石兴龙 有 20 只猫
    // logn 函数产生的值 > n
    
    // 最慢的代码 O(n次方)
    findCat = (n) => {
        let name = '石兴龙';
        let animal = '猫';
        let cat_number = 0
        for (let i = 0; i < n; i++) {
            for (let j = 0; j < n; j++) {
                cat_number++;
            }
        }
        console.log(`${name} 有 ${cat_number} 只猫`)
    }
    findCat(10) // 石兴龙 有 100 只猫
    // for 循环的执行次数是 n 的平方,甚至更大
    

    8. 针对某一个算法的复杂度分析又分为四种情况: 最快O(1),最慢O(n),均摊O(1),和随机O(n)

    9. 最快,最慢,随机

    let cats = ['钢蛋儿', '灰灰', '三花', '豆芽']
    findCat = (catName) => {
        let name = '石兴龙';
        let animal = '猫';
        let cat_number = 0
        for (let i = 0; i < cats.length; i++) {
            if (cats[i] === catName) {
                console.log(`${catName} 排行第 ${i}`)
                break;
            }
        }
        console.log(`${catName} 不是你的猫`)
    }
    findCat('钢蛋儿') // 钢蛋儿 排行第 1
    // 执行效率最快 O(1)
    
    findCat('豆芽') // 豆芽 排行第 4
    // 执行效率最慢 O(n)
    
    findCat(parseInt(Math.random() * cats.length))
    // 平均执行效率为 O(n),因为是随机的
    

    10. 均摊 O(1):循环有规律的出现,并且能被抵消掉。

    // 插入猫,扩容数组
    let index = 4
    let insertCat = (newCatName) => {
        if (index === cats.length) {
            let newCats = []
            for (let i = 0; i < cats.length; i++) {
                newCats.push(cats[i])
            }
            cats = newCats
        }
        index++;
        cats.push(newCatName)
    }
    insertCat('金渐层') // 复杂度:O(n)
    insertCat('海双布偶') // 复杂度:O(1)
    insertCat('蓝白高地') // 复杂度:O(1)
    /*
        均摊:虽然有循环,但是循环是有规律的。
        每一次 O(n) 的后面都跟着 n - 1 次 O(1)
    */
    
  • 相关阅读:
    倒计时2(小于0时的格式)
    日期 Date()
    倒计时5(超过时间为0:0:0)
    倒计时4
    倒计时3
    Lucene_solr
    Solr与tomcat搭建(搭建好)
    SSM(Spring-SpringMvc-Mybatis)练习
    SpringMvc
    Mybatis(使用)与Spring整合
  • 原文地址:https://www.cnblogs.com/shixinglong/p/12804699.html
Copyright © 2011-2022 走看看