数据结构和算法这门计算机必修课对于技术人员来说是必须的并且对于编程能力的提高很重要。我最近正在复习数据结和算法,在这里将看的视频中的精华总结出来,争取每日一更。总结一下对于我自己来说也是一种提高。
我个人感觉,虽然我们常常说实战比书本知识更重要,但是基础知识学不好的话实战的时候只会事倍功半。我也是在上一些技术课程的过程中才体会到这个道理的。大二的时候上数据结构、数据库、计算机网络这些基础课程的时候只觉得好无聊啊以后能用来干什么,后来开始做网站做简单的小系统的时候就发现了当初那些东西并不是没有用,只是还没有到用的时候哇!
1、什么是数据结构?
官方定义就不再赘述,我们可以简单地理解为:程序设计=数据结构+算法;再简单地说的话,数据结构就是关系,是数据元素之间存在的一种或多种特定关系的集合。
2、传统上,数据结构分为逻辑结构和物理结构。逻辑结构是指数据对象中数据元素之间的相互关系;物理结构则是指数据的逻辑结构在计算机中的存储形式。逻辑结构是我们主要学习的一种结构。
3、四大逻辑结构有哪些?
(1)集合结构:集合结构中的数据元素除了同属于一个集合外,它们之间没有其他的关系;
(2)线性结构:线性结构中的数据元素之间是一对一的关系;
(3)树形结构:树形结构中的数据元素之间存在一种一对多的层次关系;就像一棵大树,一个枝干下有许多叶子;
(4)图形结构:图形结构的数据元素是多对多的关系;比如说六度分割理论;
4、数据元素有哪两种存储形式?
(1)顺序存储:是把数据元素存放在地址连续的存储单元里,其数据间的逻辑关系和物理关系是一致的,如数组结构;
顺序存储结构的优点是节省存储空间,数据元素之间的逻辑关系没有占用额外的存储空间。用这种方法来存储线性结构的数据元素时,可实现对各数据元素的随机访问。
顺序存储结构的缺点是不便于修改,在对元素进行插入、删除运算时可能要移动一系列的元素。
(2)链式存储:比顺序存储结构更加灵活,是把数据元素存放在任意的存储单元里,这组存储单元可以是连续的,也可以是不连续的;数据元素之间的逻辑关系借助于指示元素存储地址的指针来表示;链式存储结构除了存放数据元素本身,还要存放指针用来指向下一个元素的位置。
链式存储的优点是:在进行插入删除运算时不必移动结点,只需要修改节点的指针字段值;
链式存储的缺点是:存储空间的利用率较低,因为结点中需要额外开销存储空间来表示结点之间的逻辑关系;另外,这种方法存储的线性结构不能对结点进行随机访问。
5、什么是算法?
官方来说,算法是解决特定问题求解步骤的描述,在计算机中表现为指令的有限序列,并且每条指令表示一个或多个操作。通俗来说,算法就是做某件事情的技巧和方式。一个典型例子就是1+2+3+、、、、、、+100的两种计算方式,高斯算法就是一种简洁方便的算法,比起一个一个加起来快得多。
6、算法的五个基本特征?
(1)输入:算法具有零个或多个输入;
(2)输出:算法算法至少有一个或多个输出;
(3)有穷性:指算法在执行有限的步骤之后,自动结束而不会出现无限循环,并且每一个步骤都在可接受的时间内完成;
(4)确定性:算法的每个步骤都有确定的含义,不会有二义性;算法在一定条件下,只有一条执行路径,相同的输入只能有唯一的输出结果;算法的每一个步骤都应该被精确定义而无歧义;
(5)可行性:算法的每一步都必须是可行的,每一部都能通过执行有限次数来完成;
7、算法设计有什么要求?
算法不是唯一的,同一个问题可能有多种解决问题的算法。
(1)正确性:大体分为四个层次:
-算法程序没有语法错误;
-算法程序对于合法输入能够产生满足要求的输出;
-算法程序对于非法输入能够产生满足规格的说明;
-算法程序对于故意刁难的测试输入都有满足要求的输出结果;
(2)可读性:便于阅读、理解和交流;
(3)健壮性:当输入数据不合法的时候,算法也能够做出相关处理而不是产生异常、崩溃或者莫名其妙的结果;
(4)时间效率高和存储量低;
8、算法效率的度量方法有哪些?
(1)事后统计方法通过测试好的测试程序和数据,利用计算机计时器对不同算法编制的程序的运行时间进行比较,从而确定算法效率的高低。但是这种方法缺陷较大,需要事先编好测试程序,花费大量时间和精力;测试环境差别也较大。这种事后诸葛亮式的方法不合适。
(2)事前分析估算方法:在计算机程序编写前,依据统计方法对算法进行估算。
9、一个高级语言程序在计算机上运行所消耗的时间取决于下列因素:
(1)算法采用的策略和方案;
(2)编译产生的代码质量;(编译器的优劣会影响编译质量)
(3)问题的输入规模;
(4)机器执行指令的速度;
总的来说,一个程序的运行时间依赖于算法的好坏和问题的输入规模。
10、算法的时间复杂度?
(1)算法的时间复杂度:表示随着问题规模n的增大,算法执行时间的增长率和f(n)的增长率相同称作算法的渐进时间复杂度,简称时间复杂度。
简单地说,就是执行次数==时间。
用O()来体现算法时间复杂度的记法,称为大O记法。一般情况下,随着输入规模n的增大,T(n)增长最慢的算法为最优算法。就像高斯算法,不管n有多大,都只需要计算一次。
分析算法的时间复杂度的攻略总结为下:
*用常数1取代运行时间中的所有加法常数。比如运行9次就记为O(1)。
*在修改后的运行次数函数中,只保留最高阶项。如n*(n+1)/2=n^2/2+n/2,只保留最高项然后去除与最高项相乘的常数,最终得到O(n^2).
*如果最高阶项存在且不是1,则取出与这个项相乘的常数。比如3n^3,记为O(n^3)。
*得到的最后结果就是大O阶。
常见的时间复杂度如下表
例子 | 时间复杂度 | 术语 |
238372 | O(1) | 常数阶 |
3n+4 | O(n) | 线性阶 |
3n^2+4n+5 | O(n^2) | 平方阶 |
3log(2)n+4 | O(logn) | 对数阶 |
2n+3nlog(2)n+14 | O(nlogn) | nlog阶 |
n^3+2n^2+4n+8 | O(n^3) | 立方阶 |
2^n | O(2^n) | 指数阶 |
常用的时间复杂度所消耗的时间从小到大依次是:
O(1)<O(logn)<O(n)<O(nlogn)<O(n^2)<O(n^3)<O(2^n)<O(n!)<O(n^n)
平均运行时间是期望的运行时间;最坏运行时间是一种保证,在应用中,这是一种最重要的需求,通常我们提到的运行时间都是最坏情况的运行时间。
11、算法的空间复杂度?
在写代码时完全可以用空间去换时间,也可以用时间来换取空间。
算法的空间复杂度通过计算算法所需存储空间上实现,算法的空间复杂度的计算公式记作:S(n)=O(f(n)),其中n为问题的规模,f(n)为语句关于n所占存储空间的函数。
通常我们用“时间复杂度”来指运行时间的需求,用“空间复杂度”指空间需求。当直接让我们求“复杂度”时,通常指的是时间复杂度。