数据结构与算法(二)算法分析

news2025/1/24 22:50:07

算法的特性

算法具有五个基本特性:输入、输出、有穷性、确定性和可行性。

输入输出

  • 算法具有零个或多个输入
  • 至少有一个或多个输出:算法是一定需要输出的,不需要输出,你用这个算法干吗?

有穷性

指算法在执行有限的步骤之后,自动结束而不会出现无限循环,并且每一个步骤在可接受的时间内完成。现实中经常会写出死循环的代码,这就是不满足有穷性。

你说你写一个算法,计算机需要算上个二十年,一定会结束,它在数学意义上是有穷了,可是媳妇都熬成婆了,算法的意义也不就大了。

确定性

算法的每一步骤都具有确定的含义,不会出现二义性。

算法在一定条件下,只有一条执行路径,相同的输入只能有唯一的输出结果。算法的每个步骤被精确定义而无歧义。

可行性

算法的每一步都必须是可行的,也就是说,每一步都能够通过执行有限次数完成。

可行性意味着算法可以转换为程序上机运行,并得到正确的结果。

算法设计的要求

正确性

算法的正确性是指算法至少应该具有输入、输出和加工处理无歧义性、能正确反映问题的需求、能够得到问题的正确答案。

可读性

算法设计的另一目的是为了便于阅读、理解和交流。

可读性高有助于人们理解算法,晦涩难懂的算法往往隐含错误,不易被发现,并且难于调试和修改。

我们写代码的目的,一方面是为了让计算机执行,但还有一个重要的目的是为了便于他人阅读,让人理解和交流,自己将来也可能阅读,如果可读性不好,时间长了自己都不知道写了些什么。可读性是算法(也包括实现它的代码)好坏很重要的标志。

健壮性

当输入数据不合法时,算法也能做出相关处理,而不是产生异常或莫名其妙的结果。

一个好的算法还应该能对输入数据不合法的情况做合适的处理。比如输入的时间或者距离不应该是负数等。

时间效率高和存储量低

时间效率指的是算法的执行时间,对于同一个问题,如果有多个算法能够解决,执行时间短的算法效率高,执行时间长的效率低。

存储量需求指的是算法在执行过程中需要的最大存储空间,主要指算法程序运行时所占用的内存或外部硬盘存储空间。

不过,我们在实际应用中,一般更多的考虑时间效率高,以空间换取时间也是算法的常见思路。

算法效率的度量方法

事后统计方法

这种方法主要是通过设计好的测试程序和数据,利用计算机计时器对不同算法编制的程序的运行时间进行比较,从而确定算法效率的高低。

事后统计方法一般了解就行,基本没人使用。因为它有很大的缺陷,比如特别复杂的算法,本身编码就很困难,更别说编码完成后再进行测试得出算法效率,万一事后发现是很糟糕的算法,不是竹篮打水一场空吗?

事前分析估算方法

在计算机程序编制前,依据统计方法对算法进行估算。

函数渐进增长

给定两个函数f(n)g(n),如果存在一个整数N,使得对于所有的n>N,f(n)总是比g(n)大,那么我们说f(n)的增长渐近快于g(n)

image-20221225111723469

我们可以这样认为,随着n值的越来越大,它们在时间效率上的差异也就越来越大。

假设两个算法的输入规模都是n,算法A要做2n+3次操作,你可以理解为先有一个n次的循环,执行完成后,再有一个n次循环,最后有三次赋值或运算,共2n+3次操作。算法B要做3n+1次操作。

image-20221225112037313

你觉得它们谁更快呢?显然是算法A。

第二个例子,算法C是4n+8,算法D是2n^2+1

image-20221225112209854

这里的差距就更大了,显然是算法C更快。

算法时间复杂度定义

算法的时间复杂度,也就是算法的时间量度,记作:T(n)=O(f(n))。它表示随问题规模n的增大,算法执行时间的增长率和f(n)的增长率相同,称作算法的渐近时间复杂度,简称为时间复杂度。其中f(n)是问题规模n的某个函数。

用大写O( )来体现算法时间复杂度的记法,我们称之为大O记法。

一般情况下,随着n的增大,T(n)增长最慢的算法为最优算法。

推导大O阶方法

  1. 用常数1取代运行时间中的所有加法常数。
  2. 在修改后的运行次数函数中,只保留最高阶项。
  3. 如果最高阶项存在且不是1,则去除与这个项相乘

常见的大O阶

线性阶(O(n))

一般含有非嵌套循环涉及线性阶,线性阶就是随着输入规模的扩大,对应计算次数呈直线增长,例如:

public static class Ex01 {
    public static void main(String[] args) {
        int sum = 0;
        int n = 100;
        for (int i = 1; i <= n; i++) {
            sum += i;
        }
        System.out.println("sum=" + sum);
    }
}

平方阶(O(n^2))

一般嵌套循环属于这种时间复杂度

public static class Ex02 {
    public static void main(String[] args) {
        int sum = 0, n = 100;
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                sum += i;
            }
        }
        System.out.println(sum);
    }
}

立方阶(O(n^3))

一般三层嵌套循环属于这种时间复杂度。

public static class Ex03 {
    public static void main(String[] args) {
        int x = 0, n = 100;
        for (int i = 1; i <= n; i++) {
            for (int j = i; j <= n; j++) {
                for (int k = i; k <= n; k++) {
                    x++;
                }
            }
        }
        System.out.println(x);
    }
}

这种复杂度已经是爆炸式增长,实际生产肯定要重新选择算法。

对数阶(O(logn))

对于对数阶,由于随着输入规模n的增大,不管底数为多少,他们的增长趋势是一样的,所以我们会忽略底数。

public static class Ex04 {
    public static void main(String[] args) {
        int i = 1, n = 100;
        while (i < n) {
            i = i * 2;
        }
    }
}

一般二分法都是对数阶,二叉树的一些计算也是对数阶。对数阶相对于平方阶是巨大的提升,运行次数是折半的。

常数阶(O(1))

一般不涉及循环操作的都是常数阶,因为它不会随着n的增长而增加操作次数。例如:

public static class Ex05 {
    public static void main(String[] args) {
        int n = 100;
        int i = n + 2;
        System.out.println(i);
    }
}

不过我们一般也不讨论常数阶。

总结

描述增长的数量级说明举例
常数级别1普通语句将两个数相加
对数级别logN二分策略二分查找
线性级别N循环找出最大元素
线性对数级别NlogN分治思想归并排序
平方级别N^2双层循环检查所有元素对
立方级别N^3三层循环检查所有三元组
指数级别2^N穷举查找检查所有子集

他们的复杂程度从低到高依次为

O(1) < O(logn) < O(n) < O(nlogn) < O(n^2) < O(n^3)

平方级别和立方级别的算法,时间已经是爆炸式增长,而指数级别的运行时间几乎是灾难,如果发现写出的算法是平方级别、指数级别,那么肯定需要优化。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/965495.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

教你如何进行vcruntime140_1.dll文件下载安装,4种方法详细的安装方法

今天主要要跟大家说说vcruntime140_1.dll文件下载安装&#xff0c;其实要下载安装这个文件还是有不少方法的&#xff0c;只要不要慌&#xff0c;有的时候办法解决&#xff0c;首先我们要知道vcruntime140_1.dll是Microsoft Visual C的一部分&#xff0c;是许多计算机程序运行所…

Python项目打包与部署(1):模块与包的概念与关系

Python是动态类型编程语言&#xff0c;意味着python不需要提前编译。1个Python项目通常也包含多个.py文件&#xff0c; 通常也会引用python标准库&#xff0c;或第3方库&#xff0c;也存在着依赖关系。因此python项目也 当实际构建1个 Python 项目时&#xff0c;模块与包是我们…

【python基础教程】类中属性和方法的具体定义方法及使用

前言 嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 以下介绍在python的re模块中怎样应用正则表达式 &#x1f447; &#x1f447; &#x1f447; 更多精彩机密、教程&#xff0c;尽在下方&#xff0c;赶紧点击了解吧~ python源码、视频教程、插件安装教程、资料我都准备…

Mybatis1.2 查询所有数据

1.2 查询所有数据 1.2.1 编写接口方法1.2.2 编写SQL语句1.2.3 编写测试方法1.2.4 起别名解决上述问题1.2.5 使用resultMap解决上述问题1.2.6 小结 如上图所示就页面上展示的数据&#xff0c;而这些数据需要从数据库进行查询。接下来我们就来讲查询所有数据功能&#xff0c;而实…

JavaScript【转】

以下内容转载和参考自&#xff1a;w3school的JavaScript学习内容&#xff0c;HTML JavaScript。 JavaScript 使 HTML 页面更具动态性和交互性&#xff0c;前面我们都是在代码中一开始就将元素的值、属性、style样式写死&#xff0c;使用JavaScript 的话就可以对这些内容动态的更…

WordPress(6)网站侧边栏倒计时进度小工具

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 效果图在这里插入图片描述一、添加位置二、主题style.css文件中添加美化1.引入库2.添加自定义的HTML模块效果图 提示:以下是本篇文章正文内容,下面案例可供参考 一、添加位置 在主题中 child.js…

QT DAY 4

时钟&#xff1a; #include "widget.h" #include "ui_widget.h"int hour0; int min0; int sec0; int count0; Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);this->setFixedSize(800,600);timer new …

【LeetCode-中等题】200. 岛屿数量

文章目录 题目方法一&#xff1a;深度优先搜索 dfs方法二&#xff1a;广度优先搜索 bfs方法三&#xff1a;&#xff08;重点掌握&#xff09;并查集 题目 方法一&#xff1a;深度优先搜索 dfs 思路&#xff1a;让一个扫描指针扫描每一个格子&#xff0c;然后每扫到一个为1的格…

代码随想录—力扣算法题:19删除链表的倒数第N个节点.Java版(示例代码与导图详解)

19.删除链表的倒数第N个节点 力扣题目链接 更多内容可点击此处跳转到代码随想录&#xff0c;看原版文件 给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 进阶&#xff1a;你能尝试使用一趟扫描实现吗&#xff1f; 示例 1&#xff1…

浅析Linux系统I/O模型

文章目录 概述阻塞式I/O模型非阻塞式I/O模型I/O多路复用模型信号驱动式I/O模型异步I/O模型相关参考 概述 在操作系统中&#xff0c;I/O类操作是相对慢速的&#xff0c;应用发起一个I/O操作&#xff0c;需要等待I/O资源就绪后&#xff0c;才能继续后面的处理。这种简单的请求-响…

无涯教程-JavaScript - NORMINV函数

NORMINV函数取代了Excel 2010中的NORM.INV函数。 描述 对于指定的平均值和标准差,该函数返回正态累积分布的反函数。 语法 NORMINV (probability,mean,standard_dev)争论 Argument描述Required/OptionalProbabilityA probability corresponding to the normal distributio…

NVME Linux的查询命令-继续更新

NVME Linux的查询命令 查看NVMe设备 # nvme list 查看nvme controller 支持的一些特性 # nvme id-ctrl /dev/nvme0 查看设备smart log信息 # nvme smart-log /dev/nvme0 查看设备error 信息 # nvme error-log /dev/nvme0 设备的所有命名空间 # nvme list-ns /dev/nvmeX 检…

uni-app之android项目云打包

1&#xff0c;项目根目录&#xff0c;找到mainfest.json&#xff0c;如果appid是空的&#xff0c;需要生成一个appid 2&#xff0c;点击重新获取appid&#xff0c;这个时候需要登录&#xff0c;那就输入账号密码登录下 3&#xff0c;登陆后可以看到获取appid成功 4&#xff0c;…

企业文件加密防泄密软件系统——「天锐绿盾」

天锐绿盾是一款企业电子文件透明加密安全防泄密管理系统&#xff0c;采用文件过滤驱动技术&#xff0c;对电子文档进行实时动态保护&#xff0c;防止企业计算机信息被破坏、丢失、泄密等安全问题。 PC访问地址&#xff1a; 首页 以下是关于天锐绿盾的详细介绍&#xff1a; 透明…

密度图及山脊图绘图基础

文章目录 3 种绘制密度图方法对比多组数据、同一个核函数渐变颜色填充“山脊”图同一坐标系中多个密度图的绘制 Seaborn 的 kdeplot() 函数是 Python 中绘制密度图的方式之一&#xff0c;Matplotlib 在现阶段则没有具体的绘制密度图的函数&#xff0c;一般是结合 Scipy 库中的 …

又一关键系统上线,理想车云和自动驾驶系统登陆OceanBase

8 月 1 日&#xff0c;理想汽车公布 7 月交付数据&#xff0c;理想汽车 2023 年 7 月共交付新车 34,134 辆&#xff0c;同比增长 227.5%&#xff0c;并已连续两个月交付量突破三万。至此&#xff0c;理想汽车 2023 年累计交付量已经达到 173,251 辆&#xff0c;远超 2022 年全年…

异常处理

目录 异常处理 处理异常 方案一 方案二 小结 异常处理 程序开发过程中不可避免地会遇见异常现象在案例功能的实现中我们并没有设置如何对于程序出现异常时如何进行处理 在三层架构中&#xff0c;如果持久层程序运行出现错误&#xff0c;由于我们在三层架构中都没有设置如…

单调递增的数字【贪心算法】

单调递增的数字 当且仅当每个相邻位数上的数字 x 和 y 满足 x < y 时&#xff0c;我们称这个整数是单调递增的。 给定一个整数 n &#xff0c;返回 小于或等于 n 的最大数字&#xff0c;且数字呈 单调递增 。 public class Solution {public int monotoneIncreasingDigits…

在支付宝中 下载社会保险参保证明 方法

这里 我们打开支付宝 选择 市明中心 然后选择 社保 这里 在社保查询下 找到 个人社会参保证明查询 这里 选择好自己的省市区 文件就会出现在下面了 我们直接点击这个文件进入 下面就会有下载的选项了

VBA技术资料MF51:VBA_在Excel中突出显示唯一值

【分享成果&#xff0c;随喜正能量】世间万物&#xff0c;因果循环不休&#xff0c;你的善心善行&#xff0c;都可能成为你的善缘善果。每天忆佛念佛&#xff0c;每天都在佛菩萨的加持下生活&#xff0c;自然吉祥如意&#xff0c;法喜充满。 。 我给VBA的定义&#xff1a;VBA是…