【计算机考研408】2023考研408相关题目预测总结

前言

根据2022年真题,和历年真题编写,主要用于自我复习使用,非建议。

数据结构

选择1-时间复杂度

对于递归函数的时间复杂度计算要多加注意

  • 2012年考察过递归的时间复杂度
  1. 斐波那契递归算法的时间复杂度
    朴素递归,其他有优化的斐波那契算法过于复杂,考试第一题一般不会出
int fib(int n) {
    
    
    if (n < 1) {
    
    
        return 0;
    } else if (n <= 2) {
    
    
        return 1;
    } else {
    
    
        return fib(n - 1) + fib(n - 2);
    }
}

时间复杂度O(2^n)
2. 简单递归函数

n = 1, T(n) = 1;
n > 1. T(n) = 2 * T(n / 2) + n;

题:简单起见,设n是2的整数次幂
n = 2 k n = 2^k n=2k
T ( n ) = T ( 2 k − 1 ) + 2 k = 2 k T ( 2 0 ) + k ∗ 2 k T(n) = T(2^{k-1}) + 2^k = 2^{k}T(2^{0}) + k*2^{k} T(n)=T(2k1)+2k=2kT(20)+k2k
将k换回n
T ( n ) = n ( l o g 2 n + 1 ) T(n) = n(log2n+1) T(n)=n(log2n+1)
时间复杂度O(nlog2n)

3.简单循环程序
按循环次数老实判断,2022年408第一题迷惑性还是很高的。

选择2-栈或者队列

选择3-二叉树、树、森林

选择4-并查集

并查集常见应用

  1. 克鲁斯卡尔求最小生成树
  2. 求无向连通图的连通分量
  3. 判断无向连通图的连通性

选择5-红黑树

  • 记忆:“”左根右、根叶黑、不红红、黑路同“
  • 时间复杂度
  1. 删除O(nlog2n)
  2. 插入O(nlog2n)
  3. 查找O(nlog2n)
  • 在一棵红黑树中,如果所有结点都是黑的,那么它的形态一定是满二叉树
  • 根节点黑高为h,关键字最少有 2 h − 1 2^{h}-1 2h1
  • 最多有 2 2 h − 1 2^{2h}-1 22h1
  • n个关键字的红黑树,高度不超过 2 l o g 2 ( n + 1 ) 2log2(n+1) 2log2(n+1)
  • AVL树的查找效率通常会稍微好一点,因为红黑树是一种相对平衡

选择6-图的概念

选择7-图的应用

  1. 最短路
  • Dijkstra 单源最短路,不适合负边权
  • Floyd 各顶点之间的最短路,允许负边权,但不允许带负权值的边的回路
  • 广度优先搜索查找最短路,主要是对无权图和等权图
    以上就可以考察,该图存在负边权,但不存在带负权值的回路,问下列哪个算法可以求解最短路?
    不过考察可能性不大,模拟算法的简单步骤更为有可能。
  1. 最小生成树
    性质
  • 最小生成树不唯一

  • 最小生成树树形不唯一

  • 各边权值互不相等时,唯一

    扫描二维码关注公众号,回复: 14963862 查看本文章
  • 权值之和唯一

  • 对于生成树来说,加一条边,会形成一条回路,减一条边,会变成非调通图

  • 最小生成树的边数为顶点数-1

  • prim算法-point-加点-对边稠密

  • kruskal-加边-对边稀疏

  1. 有向无环图的描述表达式(注意化简即可)
  2. 拓扑排序(可能考算法分析题?)
  3. 关键路径(可能考算法分析题?)

选择8-B树(B-树)

2022年考察了B树的删除
对于B树的插入、失败节点n+1、

  1. 每个结点至多m颗子树,m-1个关键字
  2. 保证绝对平衡->根结点在非叶情况下至少有两个子树
  3. 叶子结点(失败结点,实际不存在),终端结点(叶子结点上一层结点)
  4. 最小高度-让每个结点尽可能地满,利用分叉去计算(n为树关键字的总数)
    ( m − 1 )( 1 + m + m 2 + . . . + m h − 1 ) = n (m-1)(1+m+m^2+...+m^h-1)=n m1)(1+m+m2+...+mh1)=n
  5. 最大高度-利用h+1层有失败节点个数为n+1个去计算(n为树关键字的总数)
    2 ∗ [ c e i l i n g ( m / 2 ) ] ( h − 1 ) = n + 1 2*[ceiling(m/2)]^(h-1)=n+1 2[ceiling(m/2)](h1)=n+1
    5.B树的高度通常不包括叶子结点

B树的插入
在这里插入图片描述

选择8-B+树

  • m阶B+树定义
  1. 同样最多m棵子树,最少ceiling(m/2)棵子树
  2. 关键字个数范围
    [ c e i l i n g ( m / 2 ) , m ] [ceiling(m/2),m] [ceiling(m/2),m]
  • 叶结点
  1. 叶结点有指向记录的指针
  2. 叶结点水平链接,以便于遍历查找

选择8-B树与B+树的区别

在这里插入图片描述

选择8-B树与B+树的相关应用

在这里插入图片描述
【参考2017年真题】B+树是应文件系统需要产生的B树的变形,前者比后者更适合实际应用中的操作系统的文件索引和数据库索引,因为前者的磁盘读写代价低,查询效率更加稳定。
(其他,编译器中词法分析使用的是有穷自动机和语法树,网络中路由表快速查找主要依靠高速缓存、路由表压缩技术、快速查找算法)

选择9-查找

  • 二叉排序树
  1. 可以问该序列是否符合二叉排序树
  • 二叉查找判定树
  1. 感觉考察该知识点,不如考察平衡二叉树或者B+树新考点
    在这里插入图片描述在这里插入图片描述
    这里【2017年选择题】考过让你判断哪个树型可能成为二叉查找判定树,较为新颖,围绕定义。
  • 平衡二叉树
  1. 平衡二叉树的调整
  2. 平衡二叉树的建立
  • Hash表的查找
  1. 线性探测法考频最高,掌握好平均查找成功的长度和平均查找失败的长度
    在这里插入图片描述

注意:查找失败的情况,比较空白位置也算一次比较;还有分母的大小
6. 线性探测法会造成“集聚”现象
7. 平方探测法,处理冲突的较好方法,可以避免“集聚”现象

选择10、11-排序算法

  1. 考察排序算法的概念
  2. 不同排序算法的差别
  • 重点:快速排序
  1. 让你判断下列序列是否符合第x趟排序
    每一次找定基准元素,都会导致将序列分为两个表,并对两个表进行快速排序【2019年选择题】
  2. 或者是让你进行一趟快速排序的结果
  • 希尔排序
  1. 近几年没见了,稍微准备下,即把相隔某个增量的记录组成一个子表,对子表进行直接插入排序

快速排序代码

void quicksort(int a[], int low, int high){
    
    
	if (low < high){
    
    
        int pos = partition(a, low, high);
    	quicksort(a, low, pos-1);
        quicksort(a, pos+1, high);
    }
}
//partition是一趟划分
int partition(int a[], int low, int high){
    
    
    int pos = a[low];//将表中第一个元素设置位枢轴
    while(low < high){
    
    
        //从右边找到第一个比枢轴值小的
        while(low < high && a[high] >= pos) --high;
        a[low] = a[high];
        while(low < high && a[low] >= pos) ++low;
        a[high] = a[low];
    }
    a[low] = pos;
    return low;
}

注:通过代码也可以看出来,一趟排序是包括一次partition和两个quicksort

内部排序算法的比较

1.
比较次数 与序列初态 无关 的算法是:简单选择排序、基数排序
比较次数 与序列初态 有关 的算法是:快速排序、直接插入排序、冒泡排序、堆排序、希尔排序、二路归并排序

排序趟数 与序列初态 无关 的算法是:直接插入排序、折半插入排序、希尔排序、简单选择排序、归并排序、基数排序
排序趟数 与序列初态 有关 的算法是:冒泡排序、快速排序

参考来源

总移动次数 与序列初态 无关 的算法是:二路归并排序、基数排序
时间复杂度 与序列初态 无关 的算法是:简单选择排序、堆排序、归并排序、基数排序

从稳定性来看,
稳定:插入排序、冒泡排序、归并排序、基数排序
不稳定:快速排序、简单选择、希尔排序、堆排序

  1. 若n较小,可以使用直接插入排序或者简单选择排序。直接插入需要记录的移动次数会比简单选择的多,记录本身信息量较大时,用简单选择排序比较好。
  2. 初始基本有序,直接插入或者冒泡排序
  3. n较大时,快速排序、堆排序、归并排序,快速排序速度快、堆排序辅助空间小于快排、但前两者不稳定,使用直接插入的归并排序算法是稳定的,可以考虑
  4. 关键字位数较少且可以分解时,基数排序

综合应用题41-算法题

反转链表1

题源1:反转链表1

比较简单,可以作为思想记忆,不太会这么直接考察

408可能考察链表的实现,

ListNode* reverseList(ListNode* head) {
    
    
        if(head == NULL) return NULL;
        //头插法
        ListNode * p = head;//工作指针,指向链表的最后一个位置,由于leetcode没有头结点后面相当于把最后一个结点当作头结点使用
        ListNode * q = head;
        while(p->next != NULL){
    
    
            p = p->next;
        }
        
        //开始头插
        //工作指针
        p->next = NULL;
        ListNode *r;
        while(q != p){
    
    
            r = q->next;
            q->next = p->next;
            p->next = q;
            q = r;
        }
        
        return p;
    }

反转链表2

题源2,反转链表2

题解

中等难度+链表,实际上是比较合适考研出题的。
代码量也不大。

  • curr:指向待反转区域的第一个节点 left;
  • next:永远指向 curr 的下一个节点,循环过程中,curr 变化以后 next 会变化;
  • pre:永远指向待反转区域的第一个节点 left 的前一个节点,在循环过程中不变。
    在这里插入图片描述

代码

ListNode* reverseBetween(ListNode* head, int left, int right) {
    
    
        
        //设置dummyNode
        ListNode *dummyNode = new ListNode(-1);//设置哑结点,就是头结点
        dummyNode->next = head;
    
        //已pre作为头结点进行头插法,使得left到right区域内反转
        ListNode * curr; //指向待反转区域的第一个结点
        ListNode * cnext; //curr的下一个结点
        ListNode * pre; //指向待反转区的前一个结点

        pre = dummyNode;
        for(int i = 0; i < left - 1; i++){
    
    
            pre = pre->next;
        }

        curr = pre->next;
        
        //拉直过后curr自己向后移动了,不需要再curr = curr->next
        for(int i = 0; i < right - left; i++){
    
    
            cnext = curr->next; //记录当前位置的下一个位置
            curr->next = cnext->next;
            cnext->next = pre->next;
            pre->next = cnext;          
        }
        return dummyNode->next;
    
    }

2019年真题-链表逆置(头插法)

题解

可以将头插法逆置分解为以下这几个步骤

注:图示2号是要头插的第一个元素,头结点是1号

  1. 头结点断开p->next = NULL;

  2. 当q不为空结点时,说明有元素进行头插法

​ (a)工作指针r指向要进行头插元素的后一个元素r=q->next;

​ (b)头结点的下一个结点指向要进行头插的结点,即为q结点p->next=q;[p的值是不会在头插过程中发生改变的,头插二字也可从此理解]

​ ©进行头插的结点断开q->next=NULL;

​ (d)头插下一个结点q=r;
在这里插入图片描述

代码

typedef struct LNode{
    
    
    ElemType data;
    struct Lnode *next;
} LNode, *LinkList;
void slove(LinkList * h){
    
    
    LinkList *p, *q, *r, *s;//工作指针
    p = q = h;
    //寻找中间结点
    while(q->next != NULL){
    
    
        p = p->next;
        q = q->next;
        if (p->next != NULL) p = p->next;
    }
    q = p->next; //令q指向后半段首结点
    p->next = NULL;
    //将后半段链表逆置
    while(q != NULL){
    
    
        r = q->next;
        q->next = p->next;
        p->next = q;
        q = r;
    }
    
    //逐一插入即可
    s = h->next;
    q = p->next;
	p->next = NULL;
    while(q != NULL){
    
    
        r = q->next;
        q->next = s->next;
        s->next = q;
        s = q->next;
        q = r;
    }
}

综合应用题-42

拓扑排序相关分析题

采用邻接表时间复杂度为O(|V|+|E|)采用邻接矩阵时间复杂度为O(|V|^2)

  1. 从AOV网中选择一个没有前驱的顶点并输出
  2. 从网中删除该顶点和所有以它为起点的有向边
  3. 重复1、2直至当前AOV网为空,或者是不存在无前驱的顶点为止。
    后一种情况说明,有向图中存在环
  • 可以考察拓扑排序的步骤
  • 考察判断一个有向图是否有环
    在这里插入图片描述
  • 问什么情况下拓扑排序不唯一,一个顶点有多个直接后继的时候
  • 对于一般的图来说,若其邻接矩阵是三角矩阵,则存在拓扑序列;但存在拓扑序列,其邻接矩阵不一定是三角矩阵

计算机组成原理

选择12-计算机系统性能指标

  • cpi
  • 时钟周期

选择13-补码

  1. 补码的表示范围
  2. 给你一个小数、整数,让你选择以下哪个16进制数是该数的补码表示

选择14-IEEE754浮点数的表示

选择15-

选择17-主存储器与cpu的连接

选择18-乘法电路的基本原理

选择19-指令系统

  1. 扩展编码方式

选择20-

选择21-I/O方式

个人认为以后的IO主要都是以选择题出现,较为简单且计算量不大,考察IO时间占时钟周期的比

IO流程与解答方法主要书写在该篇文章月光不染是非-IO流程分析与解答

2023应注重DMA方面的考察

综合应用题43-存储系统相关

关键词:cache-内存-外存、三级存储

综合应用题44-指令系统

关键词:MIPS、指令流水线、x86
个人觉得考MIPS的优先级会高于x86

操作系统

综合应用题45-PV-生产者消费者

  • 写优先
  • 读写公平法
  • 读优先(饥饿)

当有以下信息时候考虑是不是读者写者问题

  1. 两组并发进程
  2. 共享一个文件
  3. 两个或以上读者访问不会产生副作用
  4. 某个写进程和其他进程(读进程或写进程)同时访问就可能出错
  • 允许多个读者可以同时对文件执行读操作
  • 只允许一个写者往文件中写信息
  • 任一写者在完成写操作之前不允许其他读者或者写者工作
  • 写者执行写操作前,应让已有读者和写者退出、

于是,存在这么两组互斥关系

  1. 读者和写者互斥
  2. 写者和写者互斥
//读者进程
reader(){
    
    
    while(true){
    
    
    	p(WriteFirst);//如果在写则无法进行读
		//由于有多个读进程,所以对count的修改需要互斥
    	p(mutex);
        if(count == 0){
    
    
            //阻止写进程写
            p(WriteMutex);
        }
        count++;
        v(mutex);
        v(WriteFirst); //恢复对共享文件的访问
        
        reading;
        p(mutex);//读完修改count
        count--;
        if (count == 0){
    
    
            v(WriteMutex);//读完写进程才可以有机会进入;有P就有V
        }
        v(mutex);
    }
}
//写者进程
writer(){
    
    
    while(true){
    
    
		p(WriteFirst);//用于实现写优先
    
		p(WriteMutex);//用于实现写者与其他进程都互斥
			writing;
		v(WriteMutex);
	
    	p(WriteFirst);
	}
}
//信号量
semephore WriteFirst = 1; //写进程优先
semaphore WriteMutex = 1; //用于保证写者进程运行时,其他进程无法运行
semaphore mutex = 1; //实现对count的互斥访问
int count = 0;

例题:(王道冲刺课,教练与球员,更衣室)

教练=写者

球员=读者

更衣室=资源

writer(){
    
    
    while(true){
    
    
		p(WriteFirst);
    	p(WriteMutex);
    	教练使用更衣室;
    	v(WriteMutex);
    	v(WriteFirst);
	}
}
reader(){
    
    
    while(true){
    
    
        p(WriteFirst);
        
        p(mutex);
        if (count == 0){
    
    
            p(WriteMutex);
        }
        count++;
        v(mutex);
        v(WriteMutex);
        
        球员使用更衣室;
        
        p(mutex);
        count--;
        if (count == 0){
    
    
            v(WriteMutex);
        }
        v(mutex);
        
    }
}
//信号量
semephore WriteFirst = 1; //写进程优先
semaphore WriteMutex = 1; //用于保证写者进程运行时,其他进程无法运行
semaphore mutex = 1; //实现对count的互斥访问
int count = 0;

综合应用题46-内存管理

关键词:分页、内存和外存

计算机网络

综合应用题47-围绕网络拓扑进行分析

关键词:vlan、路由器、

猜你喜欢

转载自blog.csdn.net/qq_43382350/article/details/128376560