算法与数据结构概述

154 阅读4分钟

个人概述

数据结构与算法是在面试中占据了比较重要的地位,特别是在互联网企业和一些创业型公司中,掌握常用的线性数据结构、数结构、图结构和基本的算法(贪心算法、分支算法等)显得格外重要;

为什么要学习算法与数据结构?
  • 面试准备
  • 个人编程能力的提升,特别是在白板编程的情况下。另外有助于在开发过程中用好框架和类库,例如掌握Java中的ArrayList、LinkedList等底层的链表实现原理,有助于在日常的开发中进行合理的选择,提成系统的服务性能
  • 高效优雅的代码

什么是算法与数据结构?
  • 算法是对特定问题求解步骤的一种描述,是旨在解决特定问题的有序指令集(输入、输出、确定性、可行性和有穷性)
  • 数据结构是计算机存储组织数据的方式
  • 数据结构是算法的基石,程序=算法+数据结构

算法时间复杂度

为什么讨论算法复杂度?
如何评判一个算法的性能优劣?直接想法——实验测试,把代码跑一遍,通过统计、监控就能得到算法执行的时间和占用的内存大小,由于测试环境和测试数据的各异,这种直接实验的方式是难以反映算法的执行效率;
  • 不同的算法可能适应不同的输入规模
  • 不同的算法可能适应不同类型的输入
  • 同一个算法,了能由不同的程序员、用不同的语言、由不同的编译器编译
  • 同一个算法,可能被运行在不同的OS、不同体系的计算机上
为了给出一个客观的判断,需要抽象出一个理解的计算机模型,不依赖于上述的各种具体因素,准确测量和评价算法;
RAM(Random Access Model)模型的引入

在RAM模型中,算法的运行时间就与算发需要执行的指令操作次数成正比,记为T(n),即算法为求解规模为n的问题所需要执行的指令操作次数;


Big O概念的引入

大O的定义:存在常数c和函数f(n),使得当n >= c时,T(n) <= f(n),表示为T(n) = O(f(n)),它表示随着输入大小n的增大,算法执行需要的时间的增长速度可以用f(n)来描述;

与T(n)相比,f(n)更加简洁,f(n)是T(n)的临近上界,依然能够反映出增长趋势,Big O中的常数项和底次项可忽略;

常数项忽略描述:O(f(n)) = O(c * f(n)),O(f(n)) = O(c + f(n))
底次项忽略描述:O(n^a + n^b) = O(n^a),a > b > 0

如果一个算法的执行次数为T(n),那么只保留高次项,同时忽略最高项的系数后得到函数f(n),此时算法的时间复杂度就是O(f(n));

这里需要注意当程序中存在递归调用的时候,需要依赖主定理计算公式计算算法时间复杂度;

主定理

主定理最早出现在《算法导论》中,提供了分治方法带来的递归表达式的渐近复杂度分析。规模为n的问题通过分治,得到a个规模为n/b的问题,每次递归带来的额外计算为c(n^d),具体关于定理的证明可参考算法导论这本书;


常见算法的时间复杂度和空间复杂度
算法时间复杂度分析是一个很重要的问题,任何一个程序员都应该熟练掌握其概念和基本方法,而且要善于从数学层面上探寻其本质,才能准确理解其内涵。

           

其中c是一个常量,如果一个算法的复杂度为c、log2^n、n、n*log2^n,那么这个算法的时间效率比较高,如果是2^n、n!,那么稍微大一些的n就会命令这个算法不能动了

总结

小编建议大家平成可以在LeetCode、lincode等平台上多练习并掌握一些基础的算法思维和语言编程,同时可以看看《大话数据结构》、《计算机程序设计艺术》等了解常用的数据结构和基础算法;当然后续也将持续对基础的线性结构,树结构和图结构做持续更新;