第一次用,纯当作每日复习了
数据结构
常见重点问题
1.时间复杂度
时间复杂度是衡量算法执行时间随着输入规模增加的度量方式,一般由循环或递归决定。
计算方法:
1.先找到执行次数最多的操作
2.确定输入规模:n,m...
3.建立操作次数的函数T(n)
4.求解时间复杂度:省略低阶项和高阶项的系数,得到O(f(n))
常见的时间复杂度(一般会问常见排序的时间复杂度)
2.快速排序
基本思想:选定一个基准元素(pivot),将待排序列分为较小的和较大的两个子序列,再对子序列进行递归排序。(分治的思想)每次分区操作都会确定一个元素的位置。
时间复杂度:平均:O(nlogn) 最差:O(n^2)——待排序列基本有序
改善时间复杂度的方法:(1)随机选择基准元素(2)三数取中法(3)对小规模子序列使用插入排序
空间复杂度:O(logn)
3.哈希表(散列表)、散列查找
通过把关键码值映射到表中指定位置来访问记录,以加快查找速度。这个映射函数就叫散列函数。
散列函数构造方法:直接定址法,数字分析法,平方取中法,除留余数法
哈希冲突:多个关键字映射到同一位置
冲突解决方法:
(1)开放定址法(再散列法):线性探测再散列、二次探测再散列、随机探测再散列
(2)拉链法:同义词用单链表连接起来
4.图的存储方式
邻接矩阵法:空间复杂度O(n^2),对于稀疏图会浪费空间 。 访问效率:O(1)
邻接表:空间复杂度O(n+e) (n为结点数,e为边数) 访问效率:需要遍历链表来查找某节点的相邻节点,开销可能会比较大;对于稀疏图开销较小。
十字链表——有向图
邻接多重表——无向图
5.深度优先遍历与广度优先遍历
DFS/BFS的时间复杂度:
邻接矩阵表示的情况下:O(V^2)
邻接表表示的情况下:O(V+E)
6.循环队列的顺序表
(1)循环队列的顺序表中为什么要空一个位置?
为了区分队空与队满。
(2)两种改进方法:
增设一个记录当前队列长度的变量Q.size
增设tag变量,最后一次是删除操作时,tag=0;最后一次是插入操作时,tag=1;
7.头指针与头结点的区别
头指针:指向第一个结点(头结点或首源结点)的指针
首元结点:链表中存储第一个数据元素的结点
头结点:链表首元结点之前的一个结点
头结点的优点:
(1)使得对链表第一个结点的操作与对其它结点的操作一致(有利于对队头的操作)
(2)使得链表为空时与非空时操作一致
8.Prim算法与Kruskal算法
相同点:都是为了求最小生成树,基于贪心算法的思想
不同点:Prim是找离得最近的结点;Kruskal是找最短的边
9.顺序表与链表
(1)存取方式:顺序表可以随机存取;链表只能顺序存取
(2)逻辑结构与物理结构:顺序表逻辑上相邻物理上也相邻;链表不一定
(3)查找:按值查找——无序时,查找时间都为O(n);有序时,顺序表可采用折半查找O(logn)
按序号查找:顺序表O(1),链表都是O(n)
(4)插入、删除:顺序表平均需要移动半个表长的元素;链表只需更改相关结点的指针。
(5)空间分配:静态分配时,顺序表需要预先分配较大连续空间;动态分配时,需要移动大量元素,导致操作效率降低,且如果没有更大的连续存储空间,会导致分配失败
链表只在需要时申请空间,更灵活;但链表每个结点都有指针域,存储密度较小。
10.假溢出
指当队列或栈已满时,仍有空间可以用,但由于指针或索引的位置限制导致无法插入新元素。
解决办法:(1)将队列构造为循环队列(2)使用链式结构