问题引出

假设有一道题目:有一组N个数而要确定其中第k个最大者,我们称之为选择问题,那么这个程序如何编写?最直观地,至少有两种思路:

1、将N个数读入一个数组中,再通过某种简单的算法,比如冒泡排序法,以递减顺序将数组排序,则第k个位置上的元素就是我们需要的元素

2、稍微好一些的做法,将k个元素读入数组并以递减顺序排序,接着将接下来的元素再逐个读入,当新元素被读到时,如果它小于数组中的第k个元素则忽略之,否则将其放到数组中正确的位置上,同时将数组中的一个元素挤出数组,当算法终止时,位于第k个位置上的元素作为答案返回

这两种算法都很简单,但是假设我们有一千万个元素的随机文件和k=5000000进行模拟将发现,两个算法尽管最终都可以给出正确答案,但是在合理时间内均无法结束。因此,这两种算法都不能被认为是好的算法,因为从实际角度出发,它们无法在合理的时间内处理输入的数据。

数据结构和算法分析的提出

在许多问题中,一个很重要的观念是:写出一个工作程序并不够。如果这个程序在巨大的数据集上运行,那么运行时间就变成了重要的问题,我们将在接下来的文章中看到对于大量的输入如何估计程序的运行时间,尤其是如何在未具体编码的情况下比较两个程序运行的时间。我们还将看到彻底改进程序速度以及确定程序瓶颈的方法,这些方法将使得我们能够发现需要我们集中精力努力优化的那些代码段。

那么,首先,先了解一下什么是数据结构和算法分析(特别指出,后文的例子均以Java代码编写)。

数据结构

数据结构是计算机存储、组织数据的方式,是指数据相互之间存在一种或多种特定关系的数据元素的集合。通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率(这就是为什么我们要研究数据结构的原因),数据结构往往同高效的检索算法和索引技术相关。

常见的数据结构有数组、栈、队列、链表、树、散列等,这些数据结构将是本数据结构的分类中重点研究的对象。

算法分析

算法是为求解一个问题需要遵循的、被清楚指定的简单指令的集合。对于一个问题,一旦某种算法给定并且(以某种方式)被确定是正确的,那么重要的异步就是确定该算法将需要多少注入时间或空间等资源量的问题。如果:

1、一个问题的求解算法竟然需要长达一年时间,那么这种算法就很难有什么用处

2、一个问题需要若干个GB的内存的算法,在当前大多数机器上也是无法使用的

数学基础

无论是数据结构还是算法分析,都用到了大量的数学基础,下面将这些数学的基础简单总结一下:

1、指数

(1)XAXB = XA+B

(2)XA/XB = XA-B

(3)(XA)B = XABsi

(4)XN + XN = 2XN ≠ X2N

(5)2N + 2N = 2N + 1

2、对数

(1)XA = B当且仅当logxB = A

(2)logAB = logCB / logCA

(3)logAB = logA + logB,A>0且B>0

3、级数

(1)∑2i = 2N+1 - 1

(2)∑Ai = (AN+1 - 1) / (A - 1),若0i ≤ 1 / (1 - A)

4、模运算

如果N整除A、N整除B,那么就说A与B模N同余,记为A≡B(mod N)。直观地看,这意味着无论是A还是B被N去除,所得余数都是相同的,于是假如有A≡B(mod N),则:

(1)A + C ≡ B + C(mod N)

(2)AD ≡ BD (mod N)

时间复杂度

在计算机科学中,算法的时间复杂度是一个函数,它定量描述了该算法的运行时间。这是一个关于代表算法输入值的字符串的长度的函数,时间复杂度常用大O符号表述,不包括这个函数的低阶项和首项系数,使用这种方式时,时间复杂度可被称为是渐进的,他考察当输入值大小趋近无穷时的情况。

那么首先先看一个简单的例子,这里是计算Σi3的一个简单程序片段:

 1 public static void main(String[] args) 2 { 3 System.out.println(sum(5)); 4 } 5  6 public static int sum(int n) 7 { 8 int partialSum; 9 10 partialSum = 0;11 for (int i = 0; i <= n; i++)12 partialSum += i * i * i;13 14 return partialSum;15 }

对这个程序片段的分析是简单的:

1、声明不记入时间

2、第10行和都14行各占一个时间单元

3、第12行每次执行占用4个时间单元(两次乘法、一次加法和一次赋值),而执行N次共占用4N个时间单元

4、第11行在初始化i,测试i≤n和对i的自增都隐含着开销,所有这些总开销是初始化1个时间单元,所有的测试为N+1个时间单元,所有自增为N个时间单元,共2N+2个时间单元

忽略调用方法和返回值的开销,得到总量是6N+4个时间单元,按照最开始的定义不包括这个函数的低阶项和首项系数,因此我们说该方法的时间复杂度是O(N)。继而,我们顺便得出若干个一般法则:

法则一----for循环

一个for循环的运行时间至多是该for循环内部那些语句(包括测试)的运行时间乘以迭代的次数,因此假如一个for循环迭代N次,那么其时间复杂度应该为O(N)

法则二----嵌套for循环

从里向外分析这些循环,在一组嵌套循环内部的一条语句总的运行时间为该语句的运行时间乘以该组所有的for循环的大小的乘积,因此假如有以下代码:

 1 public static int mutliSum(int n) 2 { 3 int k = 0; 4 for (int i = 0; i < n; i++) 5 { 6 for (int j = 0; j < n; j++) 7 { 8 k++; 9 }10 }11 12 return k;13 }

则其时间复杂度应为O(N2)

法则三----顺序语句

将各个语句的运行时间求和即可,比如有以下代码:

 1 public static int sum(int n) 2 { 3 int k = 0; 4  5 for (int i = 0; i < n; i++) 6 k++; 7 for (int i = 0; i < n; i++) 8 { 9 for (int j = 0; j < n; j++)10 {11 k++;12 }13 }14 15 return k;16 }

第一个for循环的时间复杂度为N,第二个嵌套for循环的时间复杂度为N2,综合起来看sum方法的时间复杂度为O(N2)

常见的时间复杂度与时间效率的关系有如下的经验规则:

O(1) < O(log2N) < O(N) < O(N * log2N) < O(N2) < O(N3) < O(N!)

至于每种时间复杂度对应哪种数据结构和算法,后面都会讲到,从上面的经验规则来看:前四个算法效率比较高,中间两个差强人意,最后一个比较差(只要n比较大,这个算法就动不了了)。

python数据结构与算法分析_数据结构和算法分析相关推荐

  1. python数据结构视频百度云盘_数据结构与算法Python视频领课

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 课程简介: 本课程包含Python编程基础的基本语法及变量,基本数据结构,Code Structure,Function.让学生在学会Python基础的同 ...

  2. python通讯录管理系统设计_数据结构课程设计-通讯录管理系统(C语言版)

    ##数据结构课程设计-通讯录管理系统 一,前言 自从上次C语言课设写完后,这次数据结构课设就写的游刃有余了,很快啊,不足三天就写完了它(年轻人不讲武德),如果你认真看过我之前写的C语言课程设计-球队管 ...

  3. java对数据结构的了解_数据结构对java有用吗

    设计一个数据结构其实就是把现有的基本数据类型组织.封装起来.相对来说数据结构对于C/C++比较重要,因为JAVA类机制实在太强大了,类库其实可以理解为数据结构的封装.即使对于一些比较复杂的抽象数据类型 ...

  4. python数据结构与算法分析_数据结构与算法(Python版)

    为什么研究数据结构与算法 本周带大家进入Python版数据结构与算法的学习.想必大家都听过"算法"一词,算法的学习对编程者来说是至关重要的.首先我们先了解一下为什么要研究数据结构与 ...

  5. python顺序表数组_数据结构 | 顺序表

    什么是数据结构? 数据结构是指相互之间存在着一种或多种关系的数据元素的集合和该集合中数据元素之间的关系组成. 简单来说,数据结构就是设计数据以何种方式组织并存储在计算机中. 比如:列表.集合与字典等都 ...

  6. python实现排序算法_数据结构之(3)python实现排序算法

    常用排序与插入算法 冒泡排序 冒泡排序(英语:Bubble Sort)是一种简单的排序算法.它重复地遍历要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.遍历数列的工作是重复地进行直 ...

  7. mooc数据结构与算法python版期末考试_数据结构与算法Python版-中国大学mooc-试题题目及答案...

    数据结构与算法Python版-中国大学mooc-试题题目及答案 更多相关问题 婴儿出生一两天后就有笑的反应,这种笑的反应属于(). [判断题]填制原始凭证,汉字大写金额数字一律用正楷或草书书写,汉字大 ...

  8. python程序实现双向链表_数据结构-双向链表(Python实现)

    数据结构在编程世界中一直是非常重要的一环,不管是开发还是算法,哪怕是单纯为了面试,数据结构都是必修课,今天我们介绍链表中的一种--双向链表的代码实现. 好了,话不多说直接上代码. 双向链表 首先,我们 ...

  9. python基础刷题_数据结构与算法LeetCode刷题(Python)

    参考资料: 一.链表 1.  链表的必备知识要点(包括基础知识.刷题中使用的STL等知识) 2.  链表逆序(LeetCode 92 ,206. Reverse Linked List 1,2) 3. ...

最新文章

  1. 比特币现金开发者:BCH网络将“提升到VISA级别”来处理交易
  2. null in JavaScript
  3. Android直播app用什么技术可以做到延迟小一些?
  4. Linux 软件包管理命令
  5. Java微服务:蛋糕是骗人的,但您不能忽略它
  6. netbeans7.4_NetBeans 7.1:创建自定义提示
  7. php layui 上传文件,laravel使用layui 上传文件 支持pdf上传
  8. dubbo-admin安装和简单使用
  9. python扫描端口脚本_python扫描端口脚本
  10. Java基础(1):Java简介和开发环境配置
  11. 物联网平台发展前景如何快速发展
  12. 收藏|2021年浅谈多任务学习
  13. Extjs Grid 数据绑定 json 分页 不分页
  14. java session 例子_JavaWeb——HttpSession常用方法示例
  15. js读取json文件
  16. 数学分析(1):集合相关公式的证明
  17. 一个2022本科生的秋招总结 (大疆、Arm、小米、荣耀、美团、联发科等)
  18. linux进阶52——pthread_cond_t
  19. MGMT接口采集服务器IMM日志
  20. 电路基础——NMOS物理结构

热门文章

  1. spark sql合并小文件_Spark SQL小文件问题在OPPO的解决方案
  2. js设计一个带开关的时钟_数电题:三个按键一个灯
  3. 北京联合大学计算机学院在哪个校区,北京联合大学各校区联系地址大全
  4. MFC对话框绘制灰度直方图
  5. CSAPP--整数的运算
  6. 近代数字信号处理实验-DFT分析信号的频谱
  7. 辗转相除法--最大公约数/最大公倍数
  8. Android代码导出数据库,导入/导出到android sqlite数据库
  9. oracle 数据掩码,oracle格式掩码
  10. python语言打印菱形_Python 实现打印单词的菱形字符图案