原程序员的算法课(1)-算法概述2019年08月18日 17:58:49 十步杀一人_千里不留行 阅读数 11更多所属专栏: 程序员的算法课编辑

【算法之美】数据结构+算法=程序。

前言

数据结构只是静态的描述了数据元素之间的关系。高效的程序需要在数据结构的基础上设计和选择算法。

高效的程序=恰当的数据结构+合适的算法

算法(Algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制。也就是说,能够对一定规范的输入,在有限时间内获得所要求的输出。如果一个算法有缺陷,或不适合于某个问题,执行这个算法将不会解决这个问题。不同的算法可能用不同的时间、空间或效率来完成同样的任务。一个算法的优劣可以用空间复杂度时间复杂度来衡量。

一、算法的特性

  1. 输入:算法具有0个或多个输入;
  2. 输出:算法至少有1个或多个输出;
  3. 有穷性:算法在有限的步骤之后会自动结束而不会无限循环;
  4. 确定性:算法中的每一步都有确定的含义,不会出现二义性;
  5. 可行性:算法的每一步都是可行的;
  6. 可读性:算法可读性是最容易被忽视的,要注意,程序是写给人看的,而不是计算机

二、算法效率的衡量

【时间复杂度】同一个问题可以用不同算法来解决,而一个算法的好坏将影响到程序的执行效率。时间复杂度是一个函数,它定性描述了该算法的运行时间。复杂度越低,程序越高效。

【空间复杂度】(Space Complexity)是对一个算法在运行过程中临时占用存储空间大小的量度。占用空间越小,复杂度越低。

三、时间复杂度

时间复杂度常用大O符号表述,即大O表示法。

算法效率严重依赖于操作(Operation)数量,在判断时首先关注操作数量的最高次项,操作数量的估算可以作为时间复杂度的估算。如下的例子:

  • O(5) = O(1)
  • O(2n + 1) = O(2n) = O(n)
  • O(n2 + n + 1) = O(n2)
  • O(3n3+1) = O(3n3) = O(n3)

常见的时间复杂度有:

  • 常数阶O(1),
  • 对数阶O(log2 n),
  • 线性阶O(n),
  • 线性对数阶O(n log2 n),
  • 平方阶O(n^2),
  • 立方阶O(n^3)
  • k次方阶O(n^K),
  • 指数阶O(2^n)。

关系:

随着n的不断增大,时间复杂度不断增大,算法花费时间越多。

时间复杂度的计算:

  1. 如果算法的执行时间不随着问题规模n的增加而增长,即使算法中有上千条语句,其执行时间也不过是一个较大的常数。此类算法的时间复杂度是O(1)。
  2. 当有若干个循环语句时,算法的时间复杂度是由嵌套层数最多的循环语句中最内层语句的频度f(n)决定的。
  3. 循环不仅与n有关,还与执行循环所满足的判断条件有关。
  4. 在没有特殊说明时,我们所分析的算法的时间复杂度都是指最坏时间复杂度。

四、空间复杂度

算法的空间复杂度通过计算算法的存储空间实现。

S(n) = O(f(n))

其中,n为问题规模,f(n)为在问题规模为n时所占用存储空间的函数。

计算方法:

  1. 忽略常数,用O(1)表示
  2. 递归算法的空间复杂度=递归深度N*每次递归所要的辅助空间
  3. 对于单线程来说,递归有运行时堆栈,求的是递归最深的那一次压栈所耗费的空间的个数,因为递归最深的那一次所耗费的空间足以容纳它所有递归过程。

五、方法

递推法

递推是序列计算机中的一种常用算法。它是按照一定的规律来计算序列中的每个项,通常是通过计算机前面的一些项来得出序列中的指定项的值。其思想是把一个复杂的庞大的计算过程转化为简单过程的多次重复,该算法利用了计算机速度快和不知疲倦的机器特点。

递归法

程序调用自身的编程技巧称为递归(recursion)。一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法。递归就是在过程或函数里调用自身; 在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口。

穷举法

穷举法,或称为暴力破解法,其基本思路是:对于要解决的问题,列举出它的所有可能的情况,逐个判断有哪些是符合问题所要求的条件,从而得到问题的解。它也常用于对于密码破译,即将密码进行逐个推算直到找出真正的密码为止。

贪心算法

贪心算法是一种对某些求最优解问题的更简单、更迅速的设计技术。

用贪心法设计算法的特点是一步一步地进行,常以当前情况为基础根据某个优化测度作最优选择,而不考虑各种可能的整体情况,它省去了为找最优解要穷尽所有可能而必须耗费的大量时间,它采用自顶向下,以迭代的方法做出相继的贪心选择,每做一次贪心选择就将所求问题简化为一个规模更小的子问题, 通过每一步贪心选择,可得到问题的一个最优解,虽然每一步上都要保证能获得局部最优解,但由此产生的全局解有时不一定是最优的,所以贪婪法不要回溯。

分治法

分治法是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。

动态规划法

动态规划是一种在数学和计算机科学中使用的,用于求解包含重叠子问题的最优化问题的方法。其基本思想是,将原问题分解为相似的子问题,在求解的过程中通过子问题的解求出原问题的解。

迭代法

迭代法也称辗转,是一种不断用变量的旧值递推新值的过程,跟迭代法相对应的是直接法(或者称为一次解法),即一次性解决问题。

分支界限法

分支定界法的基本思想是对有约束条件最优化问题的所有可行解(数目有限)空间进行搜索。

回溯法

回溯法(探索与回溯法)是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。

六、总结

  1. 算法是为了解决实际问题而设计的
  2. 数据结构是算法需要处理的问题载体
  3. 数据结构与算法相辅相成
  4. 多数情况下,算法执行时所用的时间更令人关注
  5. 如果有必要,可以通过增加空间复杂度来降低时间复杂度,空间换时间
  6. 同理,也可以通过增加时间复杂度来降低空间复杂度,时间换空间

参考资料:

  1. https://blog.csdn.net/HaloTrriger/article/details/78994122
  2. https://baike.baidu.com/item/%E7%AE%97%E6%B3%95/209025?fr=aladdin


我的微信公众号:架构真经(关注领取免费资源)

原文地址:https://www.cnblogs.com/anymk/p/11406424.html

时间: 2024-10-04 02:11:35

原程序员的算法课(1)-算法概述2019年08月18日 17:58:49 十步杀一人_千里不留行 阅读数 11更多所属专栏: 程序员的算法课编辑的相关文章

2019年5月18日-linux就该这么学-第8课

第6章 存储结构与磁盘划分 6.2 物理设备的命名规则(1) SCSI/SATA/U盘---/dev/sd[a-p]:可挂16块硬盘或硬件设备.(2) 主分区或扩展分区的编号:1-4:逻辑分区比编号5开始.(3) 首扇区信息:主引导记录:446字节:分区表:64字节,单分区表16字节,共4个:结束符2字节.6.3 文件系统与数据资料(1)文件系统:RHEL5---ext3;RHEL6---ext4+1EB;RHEL7---xfs+18EB; (2) VFS架构:用户界面(用户进程-)--内核(系

第一章 部署虚拟环境linux系统 2019年7月15日星期一 第二课

第一章 部署虚拟环境linux系统 2019年7月15日星期一  第二课 1.1 准备的工具 VmawareWorkSation 12.0   虚拟机 RadHatEnterpriseLinux[RHEL]7.0   红帽操作系统 1.2 安装配置VM虚拟机 略…… 1.3 安装配置VM虚拟机 VM配置要开启BIOS里的inte-TV  虚拟化服务 1.4 配置root用户密码 红帽RHCSA考前辅导视频 1.5 Rpm红帽软件包 (1)源代码安装弊端:1.难度高,安装困难. 2.需要自己解决依

二周第一次课(12月18日)

二周第一次课(12月18日)2.6 相对和绝对路径2.7 cd命令2.8 创建和删除目录mkdir/rmdir2.9 rm命令 相对和绝对路径: (根./)下的文件目录是绝对路径:[[email protected] ~]# ls /etc/sysconfig/network-scripts/ifcfg-ens33/etc/sysconfig/network-scripts/ifcfg-ens33 (当前目录下的文件目录)是相对路径:[[email protected] ~]# pwd/root

基于 Autojs 的 APP、小程序自动化测试 SDK - 2019年8月3日

原文:https://blog.csdn.net/laobingm/article/details/98317394 autojs sdk基于 Autojs 的 APP.小程序自动化测试 SDK,支持:启动应用.停留等待.判断存在.文本点击.颜色点击.循环点击.坐标拾取.语音播报.通知栏提示.音量调节.震动等数十项能力. autojs sdk 在 Auto.js 的基础上,通过大量接口优化提升了模块的通用性,并进行丰富的功能扩展. 运行环境下载下载方式:sdk 测试阶段请加群下载 autojs

《程序员的思维修炼》摘抄start:2014年9月27日19:27:07

程序员的思维修炼:摘抄:考虑到社会中各个相关团体的复杂交互影响和社会的持续变化,在我看来当前最重要的两项技能就是: ?沟通能力: ?学习和思考能力.软件行业正在逐步提高沟通能力.特别是敏捷方法(见注解栏),强调了团队成员之间.最终客户和开发团队之间的沟通交流. 程序员需要不断地学习——不仅仅是学习新技术,还包括应用的问题域.用户社区的奇思妙想.同事的古怪习惯.行业的八卦新闻和项目演进的重要特征,我们必须学习学习再学习,持续不断地学习,然后把学习成果应用到解决日常遇到的一切新旧问题上. 专家精通者

2019年5月26日-linux就该这么学-第11课

第9章 使用 ssh服务管理远程主机 9.1 配置网络服务9.1.1 配置网络参数--nmtui(1) 网卡配置文件中 ONBOOT yes,这样在系统重启后网卡就被激活了.(2) 手动重启服务:systemctl restart network:9.1.2 创建网络会话--网络会话功能允许用户在多个配置文件中快速切换.nmcli--基于命令行的网络配置工具,用于管理NetworkManager服务.(1) 查看网络连接情况:nmcli connection show:(2) 配置company

一个验证登录的程序:python编写flask架构restful风格--2017年4月6日

一个验证登录的程序 摘抄自:极客学院-Python RESTful API开发工具介绍及应用   http://www.jikexueyuan.com/course/623.html import base64 import time import random from flask import Flask,request app = Flask(__name__) users = { "magigo": ["123456"] } def gen_token(ui

4月18日发现一款比较好用的文本文件编辑前软件EverEdit

EverEdit – 轻量级纯文本编辑器 初步尝试了一下还是比较好用,不过是需要付费的,额,好吧.我只能使用30天,30天之后哥要想办法弄到破解版本,穷啊. ps:购买了一套EXCEL VBA编程基础,很多同学可能认为看起来很简单的样子,不过对于我这种程序小白来讲,还是值得研究和学习的,学会初步的vba语言,对工作效率的提升会有很大的帮助.

JAVA 最初的接触 2019年 1 月 6 日 任何程序本质就是:变量、选择语句、循环语句

程序就是现实逻辑的表达 程序的本质:变量 .if 语句 .循环语句 第一个非程序 一个公司的逻辑 考勤办法: 1.上班时间是9:00,打卡时间晚于9点则是迟到 2.打卡时间迟到10分钟,则扣打卡人工资10元 3.打卡时间迟到10分钟到60分钟,则扣打卡人工资100元 4.打开时间迟到1小时以上.罚做俯卧撑100个,直到坐满100个才能坐上工位上班. 逻辑: (学会后一定回头写一个完整的代码补充) kaoqin(打卡人,打卡时间) { 上班时间 = 9: if (0 < 打卡时间 - 上班时间 <