须要pdf直接打印版,可在公众号"程序员宝藏"回复复试上岸获取(会持续更新)程序员
在复习过程当中,我用心查阅并整理了在考研复试面试中可能问到的大部分问题,并分点整理了答案,能够直接理解背诵并加上本身的语言润色!极力推荐打印下来看,效率更高!面试
声明:一些边边角角的没有收集,毕竟是考研面试,不是笔试,这样也能减轻你们的负担!算法
此系列一共有8篇:编程语言篇**|数据结构篇|操做系统篇|组成原理篇|计算机网络篇|数据库篇|软件工程篇|计算机专业英语篇**(还未所有完成,敬请期待,大家的支持和关注是我最大的动力!)数据库
我的整理,不可用于商业用途,转载请注明出处。编程
须要408电子书2021版,可在公众号"程序员宝藏"回复408电子书获取数组
须要408初试视频2021版,可在公众号"程序员宝藏"回复408视频获取网络
须要复试机试视频,可在公众号"程序员宝藏"回复机试必过获取数据结构
加油,你们均可以上岸!!!让咱们一块儿努力!!!框架
快速唤起记忆知识框架:编程语言
1 .时间复杂度
ps:我看到一个学长回忆说老师问了他 大O 是什么意思???若是是我,估计当场蒙蔽了,毕竟平时知道作题就行,也没仔细看 大O 什么意思,因此你们仍是看看这题。有备无患。
一个语句的频度是指该语句在算法中被重复执行的次数。算法中全部语句的频度之和记为T(n), 它是该算法问题规模n 的函数,时间复杂度主要分析T(n) 的数量级。算法中基本运算(最深层循环内的语句)的频度与T(n) 同数量级,所以一般采用算法中基本运算的频度f(n)来分析算法的时间复杂度。所以,算法的时间复杂度记为 T(n) = O(f(n))
取f(n) 中随n 增加最快的项,将其系数置为1 做为时间复杂度的度量。例如, f(n) = an^3^ + bn^2^ + cn 的时向复杂度为O(n^3^)
上式中, O 的含义是T(n) 的数量级,其严格的数学定义是:若T(n)和f(n)是定义在正整数集合上的两个函数,则存在正常数C 和n~0~,使得当n >= n~0~时,都知足0 <=T(n) <=Cf(n) 。 算法的时间复杂度不只依赖于问题的规模n, 也取决于待输入数据的性质(如输入数据元素 的初始状态)
2.空间复杂度
算法的空间复杂度S(n)定义为该算法所耗费的存储空间,它是问题规模n 的函数。记为 S(n) = O(g(n)) 一个程序在执行时除须要存储空间来存放自己所用的指令、常数、变量和输入数据外,还须要一些对数据进行操做的工做单元和存储一些为实现计算所需信息的辅助空间。若输入数据所占空间只取决于问题自己,和算法无关,则只需分析除输入和程序以外的额外空间。 算法原地工做是指算法所需的辅助空间为常量,即O(1) 。
3.数的逻辑结构
指的是数据元素之间逻辑关系,与数的存储结构无关,是独立于计算机的,如下是分类图。
4.数的存储结构
存储结构是指数据结构在计算机中的表示,也称物理结构,主要有如下4种:
顺序存储。把逻辑上相邻的元素存储在物理位置上也相邻的存储单元中,元素之间的关系由存储单元的邻接关系来体现。其优势是能够实现随机存取,每一个元素占用最少的存储空间;缺点是只能使用相邻的一整块存储单元,所以可能产生较多的外部碎片。
链式存储。不要求逻辑上相邻的元素在物理位置上也相邻,借助指示元素存储地址的指针来表示元素之间的逻辑关系。其优势是不会出现碎片现象,能充分利用全部存储单元;缺点是每一个元素因存储指针而占用额外的存储空间,且只能实现顺序存取。
索引存储。在存储元素信息的同时,还创建附加的索引表。索引表中的每项称为索引项,索引项的通常形式是(关键字,地址)。其优势是检索速度快;缺点是附加的索引表额外占用存储空间。另外,增长和删除数据时也要修改索引表,于是会花费较多的时间。
散列存储。根据元素的关键字直接计算出该元素的存储地址,又称哈希(Hash) 存储。其优势是检索、增长和删除结点的操做都很快;缺点是若散列函数很差,则可能出现元素存储单元的冲突,而解决冲突会增长时间和空间开销。
5.用循环比递归的效率高吗?
循环和递归二者是能够互换的,不能决定性的说循环的效率比递归高。
递归的优势是:代码简洁清晰,容易检查正确性;缺点是:当递归调用的次数较多时,要增长额外的堆栈处理,有可能产生堆栈溢出的状况,对执行效率有必定的影响。
循环的优势是:结构简单,速度快;缺点是:它并不能解决所有问题,有的问题适合于用递归来解决不适合用循环。
6.贪心算法和动态规划以及分治法的区别?
贪心算法顾名思义就是作出在当前看来是最好的结果,它不从总体上加以考虑,也就是局部最优解。贪心算法从上往下,从顶部一步一步最优,获得最后的结果,它不能保证全局最优解,与贪心策略的选择有关。
动态规划是把问题分解成子问题,这些子问题可能有重复,能够记录下前面子问题的结果防止重复计算。动态规划解决子问题,前一个子问题的解对后一个子问题产生必定的影响。在求解子问题的过程当中保留哪些有可能获得最优的局部解,丢弃其余局部解,直到解决最后一个问题时也就是初始问题的解。动态规划是从下到上,一步一步找到全局最优解。(各子问题重叠)
分治法(divide-and-conquer):将原问题划分红n个规模较小而结构与原问题类似的子问题;递归地解决这些子问题,而后再合并其结果,就获得原问题的解。(各子问题独立)
分治模式在每一层递归上都有三个步骤:
分解(Divide):将原问题分解成一系列子问题; 解决(conquer):递归地解各个子问题。若子问题足够小,则直接求解; 合并(Combine):将子问题的结果合并成原问题的解。
例如归并排序。
快速唤起记忆知识框架:
7.顺序表和链表的比较
1.存取(读写)方式 顺序表能够顺序存取,也能够随机存取,链表只能从表头顺序存取元素。例如在第i个位置上执行存或取的操做,顺序表仅需一次访问,而链表则需从表头开始依次访问i次。
2.逻辑结构与物理结构 采用顺序存储时,逻辑上相邻的元素,对应的物理存储位置也相邻。而采用链式存储时,逻辑上相邻的元素,物理存储位置则不必定相邻,对应的逻辑关系是经过指针连接来表示的。
3.查找、插入和删除操做 对于按值查找,顺序表无序时,二者的时间复杂度均为O(n); 顺序表有序时,可采用折半查找,此时的时间复杂度为O(log2n) 。
对于按序号查找,顺序表支持随机访问,时间复杂度仅为0(1), 而链表的平均时间复杂度为O(n) 。顺序表的插入、删除操做,平均须要移动半个表长的元素。链表的插入、删除操做,只需修改相关结点的指针域便可。因为链表的每一个结点都带有指针域,故而存储密度不够大。
4.空间分配 顺序存储在静态存储分配情形下,一旦存储空间装满就不能扩充,若再加入新元素,则会出现内存溢出,所以须要预先分配足够大的存储空间。预先分配过大,可能会致使顺序表后部大量闲置;预先分配太小,又会形成溢出。动态存储分配虽然存储空间能够扩充,但须要移动大量元素,致使操做效率下降,并且若内存中没有更大块的连续存储空间,则会致使分配失败。链式存储的结点空间只在须要时申请分配,只要内存有空间就能够分配,操做灵活、高效。
8.头指针和头结点的区别?
头指针:是指向第一个节点存储位置的指针,具备标识做用,头指针是链表的必要元素,不管链表是否为空,头指针都存在。
头结点:是放在第一个元素节点以前,便于在第一个元素节点以前进行插入和删除的操做,头结点不是链表的必须元素,无关紧要,头结点的数据域也能够不存储任何信息。
快速唤起记忆知识框架:
9.栈和队列的区别?
队列是容许在一段进行插入另外一端进行删除的线性表。队列顾名思义就像排队同样,对于进入队列的元素按“先进先出”的规则处理,在表头进行删除在表尾进行插入。因为队列要进行频繁的插入和删除,通常为了高效,选择用定长数组来存储队列元素,在对队列进行操做以前要判断队列是否为空或是否已满。若是想要动态长度也能够用链表来存储队列,这时要记住队头和对位指针的地址。
栈是只能在表尾进行插入和删除操做的线性表。对于插入到栈的元素按“后进先出”的规则处理,插入和删除操做都在栈顶进行,与队列相似通常用定长数组存储栈元素。因为进栈和出栈都是在栈顶进行,所以要有一个size变量来记录当前栈的大小,当进栈时size不能超过数组长度,size+1,出栈时栈不为空,size-1。
10.共享栈
利用栈底位置相对不变的特性,可让两个顺序栈共享一个一维数组空间,将两个栈的栈底分别设置在共享空间的两端,两个栈顶向共享空间的中间延伸。这样可以更有效的利用存储空间,两个栈的空间相互调节,只有在整个存储空间被占满时才发生上溢。
11.如何区分循环队列是队空仍是队满?
普通状况下,循环队列队空和队满的断定条件是同样的,都是Q.front == Q.rear。
ps:队头指针指向第一个数;队尾指针指向最后一个数的下一个位置,即将要入队的位置。
方法一:牺牲一个单元来区分队空和队满,这个时候(Q.rear+1)%MaxSize == Q.front才是队满标志 。
方法二:类型中增设表示元素个数的数据成员。这样,队空的条件为Q.size == 0;队满的条件为Q.size == MaxSize。
12.栈在括号匹配中的算法思想?
括号匹配算法思想
(1)出现的凡是“左括号”,则进栈;
(2)出现的是“右括号”,
首先检查栈是否空?
若栈空,则代表该“右括号”多余
不然和栈顶元素比较?
若相匹配,则栈顶“左括号出栈”
不然代表不匹配
(3)表达式检验结束时,
若栈空,则代表表达式中匹配正确
不然代表“左括号”有余;
13.栈在经过后缀表达式求值的算法思想?
顺序扫描表达式的每一项,而后根据它的类型作以下相应操做:若该项是操做数,则将其压入栈中;若该项是操做符,则连续从栈中退出两个操做数y 和x, 造成运算指令XY, 并将计算结果从新压入栈中。当表达式的全部项都扫描并处理完后,栈顶存放的就是最后的计算结果。
![]()
14.栈在递归中的应用?
递归是一种重要的程序设计方法。简单地说,若在一个函数、过程或数据结构的定义中又应 用了它自身,则这个函数、过程或数据结构称为是递归定义的,简称递归。 它一般把一个大型的复杂问题层层转化为一个与原问题类似的规模较小的问题来求解,递归 策略只需少许的代码就能够描述出解题过程所须要的屡次重复计算,大大减小了程序的代码量。但在一般状况下,它的效率并非过高。
将递归算法转换为非递归算法,一般须要借助栈来实现这种转换。
15.队列在层次遍历中的做用?
在信息处理中有一大类问题须要逐层或逐行处理。这类问题的解决方法每每是在处理当前层 或当前行时就对下一层或下一行作预处理,把处理顺序安排好,待当前层或当前行处理完毕,就能够处理下一层或下一行。使用队列是为了保存下一步的处理顺序。下面用二叉树层次遍历的例子,说明队列的应用。
![]()
16.队列在计算机系统中的应用?
队列在计算机系统中的应用很是普遍,如下仅从两个方面来简述队列在计算机系统中的做用:第一个方面是解决主机与外部设备之间速度不匹配的问题,第二个方面是解决由多用户引发 的资源竞争问题。
对于第一个方面,仅以主机和打印机之间速度不匹配的问题为例作简要说明。主机输出数据给打印机打印,输出数据的速度比打印数据的速度要快得多,因为速度不匹配,若直接把输出的 数据送给打印机打印显然是不行的。解决的方法是设置一个打印数据缓冲区,主机把要打印输出的数据依次写入这个缓冲区,写满后就暂停输出,转去作其余的事情。打印机就从缓冲区中按照先进先出的原则依次取出数据并打印,打印完后再向主机发出请求。主机接到请求后再向缓冲区写入打印数据。这样作既保证了打印数据的正确,又使主机提升了效率。因而可知,打印数据缓冲区中所存储的数据就是一个队列。
对于第二个方面, CPU (即中央处理器,它包括运算器和控制器)资源的竞争就是一个典型 的例子。在一个带有多终端的计算机系统上,有多个用户须要CPU 各自运行本身的程序,它们分别经过各自的终端向操做系统提出占用CPU 的请求。操做系统一般按照每一个请求在时间上的前后顺序,把它们排成一个队列,每次把CPU 分配给队首请求的用户使用。当相应的程序运行结束或用完规定的时间间隔后,令其出队,再把CPU 分配给新的队首请求的用户使用。这样既能知足每一个用户的请求,又使CPU 可以正常运行。
17.矩阵的压缩存储
数据结构中,提供针对某些特殊矩阵的压缩存储结构。这里所说的特殊矩阵,主要分为如下两类:
- 含有大量相同数据元素的矩阵,好比对称矩阵;
- 含有大量 0 元素的矩阵,好比稀疏矩阵、上(下)三角矩阵;
针对以上两类矩阵,数据结构的压缩存储思想是:矩阵中的相同数据元素(包括元素 0)只存储一个。
快速唤起记忆知识框架:
18.串的模式匹配
子串的定位操做一般称为串的模式匹配,他求的是子串(常称模式串)在主串中的位置。
暴力模式匹配算法的思想是:从主串的第一个字符起,与子串的第一个字符比较,相等则继续比较;不等则从主串的下一个位置起,继续和子串开始比较,直到最后看是否匹配成功。
如下的子串为:‘abcac’:
![]()
改进的模式匹配算法-----KMP算法:
在暴力匹配中,每趟匹配失败都是模式后移一位再从头开始比较。而某趟已匹配相等的字符 序列是模式的某个前缀,这种频繁的重复比较至关于模式串在不断地进行自我比较,这就是其低效率的根源。所以,能够从分析模式自己的结构着手,若是已匹配相等的前缀序列中有某个后缀正好是模式的前缀,那么就能够将模式向后滑动到与这些相等字符对齐的位置,主串i指针无须回溯,并继续从该位置开始进行比较。而模式向后滑动位数的计算仅与模式自己的结构有关,与主串无关。
(此处篇幅过长,感兴趣能够直接百度KPM算法详细了解,固然要求不高的能够直接跳过,知道大体思想便可,不要被问到一问三不知就能够)