写在前面
此文章是本人在备考过程中408真题数据结构部分(2010年-2017年)的易错题及相应的知识点整理,后期复习也尝尝用到,对于知识提炼归纳理解起到了很大的作用,分享出来希望帮助到大家~
# 2010年
1.散列表处理冲突的方法
注意:装填因子的概念,可以得到散列表长度
注意:拉链法在分析查找长度时,通常只统计"关键字比较次数",而链表"空指针的对比次数"不计入查找长度
后记:这个类型题目在2024年出现,此知识点很重要,预计2025年后几年会出现在选择题中。
# 2011年
1.注意审题:树转化为二叉树
2.图中回路的概念
要牢记下面概念!!!
**回路:**首尾结点相同
**简单回路:**除了首尾节点相同,中间节点不重复-不是简单路径
**简单路径:**在路径序列中,顶点不重复出现
3.归并排序相关算法
cpp
//四、归并排序
//空间复杂度主要来自辅助数组B,空间复杂度O(n)
//时间复杂度O(nlog(n)),归并趟数log(n)趟
//二路归并排序Merge操作,时间复杂度O(n)
void Merge(int A[],int low,int mid,int high){
int i,j,k;
//将A待排序数组放入B中
for(k=low;k<high;k++){
B[k]=A[k];
}
//i,j分别表示B中两个子列表的遍历指针,k指A数组中待放入元素的位置
for(i=low,j=mid+1,k=i;i<=mid&&j<=high;k++){
if(B[i]<=B[j]){
A[k]=B[i]; //将较小的值复制到A中
i++;
}else{
A[k]=B[j];
j++;
}
}
//最后把剩余已经有序的子列表数据直接放到A的最后即可
while(i<=mid){
A[k++]=B[i++];
}
while(j<=high){
A[k++]=B[j++];
}
}
//二路归并排序函数体:递归调用
//先通过子列表只有一个元素的两两组合,然后子元素扩展到两个、四个...直到全部
void MergeSort(int A[],int low,int high){
if(low<high){
int mid=(low+high)/2; //从中间划分
MergeSort(A, low, mid); //对左半部分归并排序
MergeSort(A, mid+1, high); //对右半部分归并排序
Merge(A,low,mid,high); //对两个有序的子序列归并
}
}
# 2012年
1.图的广度优先遍历
2.邻接矩阵存储有向图,拓扑排序
不唯一的意思是这个图可能存在的拓扑序列是不唯一的。而不是说代码按照邻接矩阵找到的拓扑序列是唯一的,这个和图的不同结构(邻接矩阵、邻接表)遍历区分开。
注:有向无环图一定存在拓扑序列,题目中问的是存不存在拓扑序列,和拓扑序列是否唯一。
3.B树的删除操作
4.最小生成树
(1)Prim算法:从某一顶点开始构建生成树,每次将距离这棵树代价最小的新顶点纳入生成树
(2)Kruskal算法:每次选择一条权值最小的边使这条边的两头连通(原本连通的不选),直到所有结点都连通;判断两个顶点是否属于一个集合,可以使用并查集来实现,并查集搜索时间复杂度:
# 2013年
1.时间复杂度计算
O(m+n)=O(max(m,n))
2.平衡二叉树
操作调整过程:
一般只考察删除叶子结点的情况!!!
3.二叉排序树
新插入的结点一定是叶子结点,当删除叶子结点然后再插入这个结点时,二叉排序树结构不变。
在题设中就已经设定了折半查找法以及元素排列顺序。第一问直接忽视了折半查找需要元素有序这一要求了!!!
# 2014年
1.B树的关键字数量要求
2.前中后缀表达式
3.树中结点度的定义
4.算法题
5.图相关的结构体定义
顶点、弧;(根据实际应用)
要求路由表中的路由项尽可能少,就要用到路由聚合的知识!!!
# 2015年
较简单,略
# 2016年
1.拓扑排序
使用两个数组(一个是表示当前图中每个节点的度【这个度是实现计算好的】,另一个记录当前确定的拓扑序列)和一个栈实现排序
2.快排的代码和时间复杂度分析
快排相关知识点参考:
最核心的算法就是Partition操作:
cpp
//快排
//用第一个元素将待排序序列划分为左右两个部分,每一次划分确定一个元素位置
int Partition(int A[],int low,int high){
int pivot=A[low]; //取第一个元素作中枢结点
while(low<high){
while(A[high]>=pivot){ //右侧元素大于中枢元素,不移动
high--;
}
A[low]=A[high]; //将右侧小于中枢的元素移到左侧
while(A[low]<=pivot){ //左侧元素小于中枢元素,不移动
low++;
}
A[high]=A[low]; //将左侧大于中枢的元素移到右侧
}
A[low]=pivot; //将中枢元素放到确定位置
return low; //返回确定的中枢元素位置
}
快排函数体:递归调用Partition函数,每次调用Partition函数就确定一个元素的最终位置。
cpp
//快排函数体
void QuickSort(int A[],int low,int high){
if(low<high){//跳出递归的条件
int pivotpos=Partition(A, low, high);//划分
QuickSort(A, low, pivotpos-1); //划分左子表
QuickSort(A, pivotpos+1, high); //划分右子表
}
}
只执行Partition的过程,时间复杂度平均是O(n),每次执行都不是从头开始,可以以前一次获得的pivot确定范围去寻找。
# 2017年
1.排序效率问题
2.Prim算法复习
从某一顶点开始构建生成树,每次将距离这棵树代价最小的新顶点纳入生成树
注意:是每次将距离这棵树的最短路径的结点纳入进来,而不是只从固定节点!!!!
3.树的遍历
注意要考虑括号,明确括号在中序遍历过程中什么时候输出
cpp
//二叉树先序遍历
void PreOrder(BiTree T){
if(T!=NULL){
visitNode(T);
PreOrder(T->lchild);//递归遍历左孩子
PreOrder(T->rchild);//递归遍历右孩子
}
}
//二叉树中序遍历
void InOrder(BiTree T){
if(T!=NULL){
InOrder(T->lchild);//递归遍历左孩子
visitNode(T);
InOrder(T->rchild);//递归遍历右孩子
}
}
//二叉树后序遍历
void PostOrder(BiTree T){
if(T!=NULL){
PostOrder(T->lchild);//递归遍历左孩子
PostOrder(T->rchild);//递归遍历右孩子
visitNode(T);
}
}
# 后记
**题目来源:**计算机专业基础(408)
下载链接:
https://download.csdn.net/download/hehe_soft_engineer/89675116?spm=1001.2014.3001.5503
下一章:408真题数据结构部分(2018年-2023年)