第41题:判断有向图是否存在唯一拓扑序列
📝 题目
设计算法 int uniquely(MGraph G),判定图G是否存在唯一的拓扑序列,是则返回1,否则返回0。图采用邻接矩阵存储。
c
typedef struct {
int numVertices, numEdges;
char VerticesList[MAXV];
int Edge[MAXV][MAXV];
} MGraph;
✅ 答案
c
int uniquely(MGraph G) {
int n = G.numVertices;
int inDeg[MAXV] = {0};
// 1. 统计入度
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
if (G.Edge[i][j])
inDeg[j]++;
// 2. 共进行n步,每步必须恰好摘除一个入度为0的顶点
for (int step = 0; step < n; step++) {
int zeroCount = 0, zeroIdx = -1;
for (int i = 0; i < n; i++) {
if (inDeg[i] == 0) {
zeroCount++;
zeroIdx = i;
}
}
if (zeroCount != 1)
return 0;
inDeg[zeroIdx] = -1;
for (int j = 0; j < n; j++)
if (G.Edge[zeroIdx][j])
inDeg[j]--;
}
return 1;
}
💡 详细解释
核心定理 :一个有向无环图(DAG)的拓扑序列唯一,当且仅当 在拓扑排序的每一步中,都恰好只有一个入度为0的顶点可供选择。
算法思路:
- 遍历邻接矩阵,统计每个顶点的入度(即对应列中1的个数)。
- 共进行n步(n为顶点数),每步统计当前入度为0的顶点个数。
- 若某一步零入度顶点数≠1,返回0:
- >1:表示有多个选择,拓扑序列不唯一。
- =0:表示剩余顶点形成环,拓扑排序无法完成。
- 若n步都恰好只有一个零入度顶点,返回1。
复杂度:时间O(n²),空间O(n)。
📚 涉及知识点
知识点1:拓扑排序
定义:对有向无环图(DAG)的顶点进行线性排序,使得对每条边(u,v),u在v之前。
Kahn算法(基于入度):
- 统计所有顶点入度,将入度为0的顶点入队。
- 队头出队并输出,将其所有后继顶点入度减1。
- 若后继顶点入度变为0,则入队。
- 重复直到队列为空。若输出顶点数<n,则图中有环。
DFS算法:对每个顶点进行DFS,在回溯时将顶点加入栈,最终栈的逆序即为拓扑序列。
知识点2:拓扑序列唯一性判定
关键结论 :拓扑序列唯一的充要条件是------在拓扑排序的每一步 ,入度为0的顶点有且仅有一个。
证明思路:
- 若某步有≥2个零入度顶点,选择其中任意一个都会得到不同的序列,故不唯一。
- 若某步零入度顶点数为0且尚有顶点未处理,说明存在环,拓扑排序失败。
知识点3:邻接矩阵存储
特点:
- 空间复杂度O(n²),适合稠密图。
- 判断边(i,j)是否存在:O(1)。
- 统计某顶点入度:遍历第j列,O(n)。
- 统计某顶点出度:遍历第i行,O(n)。
第42题:二次探测法构造散列表
📝 题目
将关键字序列 20, 3, 11, 18, 9, 14, 7 依次存储到长度为11的散列表HT中。散列函数H(key) = (key×3) mod 11,冲突时探查地址序列为 Hₖ = (H₀ + k²) mod 11。
- 画出HT,计算装填因子。
- 给出查找关键字14的关键字比较序列。
- 查找关键字8失败时的散列地址。
✅ 答案
(1)散列表HT:
| 下标 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 关键字 | 11 | --- | 14 | 7 | --- | 20 | 9 | --- | --- | 3 | 18 |
装填因子 α = 7/11 ≈ 0.636
(2)查找14的关键字比较序列:3, 18, 14
(3)查找8失败时的散列地址:7
💡 详细解释
(1)构造过程:
| 关键字 | H₀ | 探测过程 | 最终地址 |
|---|---|---|---|
| 20 | 5 | 位置5空 | 5 |
| 3 | 9 | 位置9空 | 9 |
| 11 | 0 | 位置0空 | 0 |
| 18 | 10 | 位置10空 | 10 |
| 9 | 5 | 冲突→H₁=(5+1)%11=6,空 | 6 |
| 14 | 9 | 冲突→H₁=10冲突→H₂=(9+4)%11=2,空 | 2 |
| 7 | 10 | 冲突→H₁=0冲突→H₂=(10+4)%11=3,空 | 3 |
(2)查找14:
- H₀ = (14×3)%11 = 9 → 位置9存的是3(比较1次,冲突)
- H₁ = (9+1)%11 = 10 → 位置10存的是18(比较2次,冲突)
- H₂ = (9+4)%11 = 2 → 位置2存的是14(比较3次,匹配)
比较序列:3, 18, 14
(3)查找8失败:
- H₀ = (8×3)%11 = 2 → 位置2存的是14(冲突)
- H₁ = (2+1)%11 = 3 → 位置3存的是7(冲突)
- H₂ = (2+4)%11 = 6 → 位置6存的是9(冲突)
- H₃ = (2+9)%11 = 0 → 位置0存的是11(冲突)
- H₄ = (2+16)%11 = 7 → 位置7为空,查找失败
失败地址:7
📚 涉及知识点
知识点1:散列函数
定义:将关键字映射到存储位置的函数H(key)。
常见构造方法:
- 除留余数法:H(key) = key mod p,p通常取不大于表长的最大素数。
- 直接定址法:H(key) = a×key + b。
- 数字分析法:分析关键字各位数字的分布,选取均匀的位作为散列地址。
- 平方取中法:取key²的中间几位作为散列地址。
本题:H(key) = (key×3) mod 11,属于除留余数法的变体。
知识点2:冲突处理------开放定址法
线性探测法:Hₖ = (H₀ + k) mod m,k=1,2,3,...
- 优点:实现简单。
- 缺点:容易产生堆积(聚集) 现象。
二次探测法:Hₖ = (H₀ + k²) mod m,k=1,2,3,...
- 优点:减少堆积现象。
- 缺点:不能保证探测到表中所有位置。
再散列法:Hₖ = (H₀ + k×H₂(key)) mod m。
关键注意 :二次探测法中的k²是相对于初始地址H₀的增量,而非从当前位置累加。
知识点3:装填因子
定义:α = 表中记录数 / 散列表长度。
意义:α越大,冲突概率越高,查找效率越低。一般控制在0.5~0.75之间。
知识点4:查找失败的平均查找长度
查找失败时,需要探查到第一个空位置才能确认失败。ASL_失败 = 各初始地址探查到空位置的次数之和 / 散列函数取值个数。
第43题:RISC处理器指令格式与数据通路
📝 题目
计算机M字长32位,按字节编址,采用32位定长指令字。指令格式如下:
| 指令 | IR31:25 | IR24:20 | IR19:15 | IR14:12 | IR11:7 | IR6:0 |
|---|---|---|---|---|---|---|
| add | 0000000 | rs2 | rs1 | 000 | rd | 0110011 |
| slli | 0000000 | shamt | rs1 | 010 | rd | 0010011 |
| lw | imm11:5 | imm4:0 | rs1 | 010 | rd | 0000011 |
✅ 答案
(1) 最多32个通用寄存器;shamt占5位。
(2) ALUBsrc=0;F=1FDB9753H;OF=1,CF=1;无符号溢出根据CF判断。
(3) slli指令IR31:25固定为全0,Ext=0或1扩展结果相同。
(4) Ext=1(符号扩展);ALUctr=000(加法)。
(5) 一定是lw指令(IR6:0=0000011);数据地址=FFFF9CD4H。
💡 详细解释
(1) rs1/rs2/rd各占5位,2⁵=32个寄存器。shamt占5位,因为32位字长最大移位31,需要5位表示。
(2) add指令两个操作数均来自寄存器,ALUBsrc=0选择寄存器B端。8765 4321H + 9876 5432H = 1 1FDB 9753H,低32位为1FDB9753H。两个操作数最高位均为1(负数),结果最高位为0,符号位改变,OF=1。最高位产生进位,CF=1。无符号溢出看CF。
(3) slli的IR31:25=0000000,无论零扩展还是符号扩展,高位补的都是0,结果相同。
(4) lw的imm是补码偏移量,需要符号扩展,Ext=1。有效地址=Rrs1+imm,ALU执行加法,ALUctr=000。
(5) A040 A103H低7位=0000011=lw的opcode。imm=A04H,符号扩展为FFFFFA04H。FFFFA2D0H+FFFFFA04H=1 FFFF9CD4H,低32位为FFFF9CD4H。
📚 涉及知识点
知识点1:RISC指令格式
R型指令(add):操作数均为寄存器,字段包括rs1、rs2、rd、funct3、funct7、opcode。
I型指令(slli、lw):包含立即数字段,字段包括imm、rs1、funct3、rd、opcode。
关键:opcode决定指令大类,funct3/funct7区分同一大类中的不同指令。
知识点2:寄存器数量与字段位宽
n位字段可表示2ⁿ个寄存器。5位→32个寄存器。shamt位数由最大移位位数决定:32位字长→最大移位31→需5位。
知识点3:符号扩展与零扩展
符号扩展:高位补符号位,保持补码数值不变。用于有符号数运算。
零扩展:高位补0,用于无符号数运算。
lw的imm:补码表示的有符号偏移量,必须符号扩展。
知识点4:溢出标志
OF(有符号溢出) :两个同号数相加,结果符号改变;或两个异号数相减,结果符号与减数相同。
CF(无符号进位/借位) :最高位产生进位(加法)或借位(减法)。
判断规则:有符号溢出看OF,无符号溢出看CF。
知识点5:ALU控制信号
ALUctr=000→加法,001→减法,010→逻辑左移。根据指令功能选择。
第44题:C语句底层实现与存储管理
📝 题目
C语句 sum += a[i]; 对应指令序列:
assembly
slli r4, r2, 2
add r4, r3, r4
lw r5, 0(r4)
add r1, r1, r5
✅ 答案
(1) 数组a首地址:r3(03H);变量i:r2(02H);变量sum:r1(01H)。
(2) ai地址=0013 E004H;ai机器数=FFFF ECDCH;sum机器数=0000 000EH;页号=0013EH;至少2页。
(3) slli机器码=0021 2213H;short类型时汇编形式为 slli r4, r2, 1。
💡 详细解释
(1) slli r4,r2,2:r2左移2位(×4),对应int型数组索引i的字节偏移。add r4,r3,r4:r3+偏移=实际地址,r3是数组首地址。lw r5,0(r4):读取ai。add r1,r1,r5:sum+=ai,r1是sum。
(2) i=5,r4=5<<2=20=14H。ai地址=0013 DFF0H+14H=0013 E004H。小端方式,地址0013 E004H处4字节为DC、EC、FF、FF,组合为FFFF ECDCH。sum=0000 1332H+FFFF ECDCH=1 0000 000EH,低32位0000 000EH。页大小4KB,页内偏移低12位。0013 E004H>>12=0013EH。首地址页号0013DH,末地址页号0013EH,跨2页。
(3) slli r4,r2,2:rd=4=00100,rs1=2=00010,shamt=2=00010,funct3=010,opcode=0010011。拼接:0000000 00010 00010 010 00100 0010011 = 0021 2213H。short占2字节,偏移=i×2,左移1位。
📚 涉及知识点
知识点1:C语句到汇编的映射
数组访问ai:
- int型占4字节,ai地址 = 数组首地址 + i×4。
- 乘法通过左移实现:i×4 = i<<2。
- 基址加偏移寻址:
lw rd, offset(rs1),地址 = Rrs1+offset。
知识点2:小端存储
定义:低字节存放在低地址,高字节存放在高地址。
示例:32位数0xFFFFECDC在内存中(小端):
| 地址 | 内容 |
|---|---|
| 低地址 | DC |
| EC | |
| FF | |
| 高地址 | FF |
大端:高字节在低地址,与小端相反。
知识点3:页式存储管理
页大小4KB = 2¹²字节:
- 页内偏移占低12位。
- 页号 = 虚拟地址 >> 12。
- 页内偏移 = 虚拟地址 & 0FFFH。
跨页判断:若数组首地址和末地址的页号不同,则数组跨多页。
知识点4:指令编码
按字段拼接:IR31:25 | IR24:20 | IR19:15 | IR14:12 | IR11:7 | IR6:0,每4位一组转十六进制。
知识点5:数据类型与偏移量
- int(4字节):偏移 = i×4 = i<<2。
- short(2字节):偏移 = i×2 = i<<1。
- char(1字节):偏移 = i。
第45题:页式虚拟存储管理地址转换
📝 题目
虚拟地址和物理地址均为32位,页表项4字节,页大小4MB。进程P页表起始虚拟地址B8C0 0000H,物理地址6540 0000H。访问虚拟地址1234 5678H缺页,处理后物理地址BAB4 5678H。
✅ 答案
| 问题 | 答案 |
|---|---|
| 页表项虚拟地址 | B8C0 0120H |
| 页表项物理地址 | 6540 0120H |
| 页框号更新值 | 2EAH |
| 页表所在页页号 | 2E3H |
| 该页页表项虚拟地址 | B8C0 0B8CH |
| 该页表项页框号 | 195H |
💡 详细解释
页大小4MB=2²²,页内偏移占低22位,页号占高10位。
(1) 虚拟地址1234 5678H高10位=048H。页表项虚拟地址=B8C0 0000H+048H×4=B8C0 0120H。物理地址=6540 0000H+048H×4=6540 0120H。物理地址BAB4 5678H高10位=2EAH。
(2) 页表起始虚拟地址B8C0 0000H高10位=2E3H。页表项虚拟地址=B8C0 0000H+2E3H×4=B8C0 0B8CH。物理地址6540 0000H高10位=195H。
📚 涉及知识点
知识点1:虚拟地址结构
32位虚拟地址 = 页号(高10位)+ 页内偏移(低22位)。
页号位数 = 32 - log₂(页大小) = 32 - 22 = 10位。
知识点2:页表项地址计算
页表项虚拟地址 = 页表起始虚拟地址 + 页号 × 页表项大小。
页表项物理地址 = 页表起始物理地址 + 页号 × 页表项大小。
关键:页表项大小通常为4字节,页号×4才是偏移量。
知识点3:页框号提取
物理地址 = 页框号(高10位)+ 页内偏移(低22位)。
页框号 = 物理地址 >> 22。
知识点4:多级页表
本题为单级页表。多级页表中,虚拟地址被划分为多个页号字段,每级页表分别索引。
第46题:进程同步与互斥
📝 题目
缓冲区B存放数据分组,操作C1(写入,B空时可执行)、C2(读出,B非空时可执行)、C3(修改,B非空时可执行)。
✅ 答案
(1) 是临界区。C1写入共享缓冲区B,并发执行会导致数据覆盖和状态不一致。
(2) semaphore S=0; P1:C1; signal(S); P2:wait(S); C2;
(3) semaphore mutex=1; P1:wait(mutex); C3; signal(mutex); P2:wait(mutex); C3; signal(mutex);
💡 详细解释
(1) 临界区判定三要素:共享资源、竞争条件、互斥需求。C1满足全部三要素。
(2) P1先写、P2后读,是同步问题。S初值=0,P2必须等待P1的signal。最少1个信号量。
(3) P1和P2各执行C3,无顺序要求,是互斥问题。mutex初值=1,保证互斥访问。
📚 涉及知识点
知识点1:临界区与互斥
临界区:访问共享资源的代码段,必须互斥执行。
互斥:任何时刻只允许一个进程进入临界区。
临界区管理四原则:空闲让进、忙则等待、有限等待、让权等待。
知识点2:信号量机制
wait(S):S--;若S<0,阻塞。
signal(S):S++;若S≤0,唤醒一个等待进程。
初值含义:
- 互斥信号量初值=1(临界区初始可用)。
- 同步信号量初值=0(等待方初始阻塞)。
知识点3:同步与互斥的区别
| 特征 | 同步 | 互斥 |
|---|---|---|
| 目的 | 保证执行顺序 | 保护共享资源 |
| 信号量初值 | 通常为0 | 通常为1 |
| 信号量数量 | 取决于同步点 | 通常1个 |
| 典型场景 | 生产者-消费者 | 临界区保护 |
知识点4:生产者-消费者模型
标准方案:
c
semaphore empty = n; // 空缓冲区数
semaphore full = 0; // 满缓冲区数
semaphore mutex = 1; // 互斥访问
关键:先同步(wait(empty/full))再互斥(wait(mutex)),否则可能死锁。
第47题:路由协议(RIP、OSPF、BGP)
📝 题目
4个自治系统互连,AS1运行RIP,AS3内路由器数≤15,AS4内路由器数>20。外部网络136.5.16.0/20可通过AS2、AS3、AS4到达。
✅ 答案
| 问题 | 答案 |
|---|---|
| (1) | OSPF |
| (2) | 16 |
| (3) | 60s |
| (4) | R44→R13:eBGP,UPDATE报文;R13→R14/R15:iBGP |
| (5) | R14下一跳:R11;R15下一跳:R13 |
💡 详细解释
(1) AS4内路由器数可能超过20,超过RIP的15跳上限,必须选OSPF。
(2) 最多经过15个路由器,TTL每跳减1,到达时TTL≥1,初始TTL≥16。
(3) RIP每30s交换一次。0s交换初始向量,30s第1跳获得,60s第2、3跳获得。收敛时间60s。
(4) R44(AS4)与R13(AS1)不同AS→eBGP,通告路由用UPDATE。R13与R14/R15同AS→iBGP。
(5) BGP无策略时选AS路径最短。R14收到R11(3跳)和R13(3跳)并列,选R11。R15同理选R13。
📚 涉及知识点
知识点1:RIP协议
类型:距离向量协议。
度量:跳数,最大15,16为不可达。
交换周期:每30s与邻居交换完整路由表。
收敛:逐跳传播,收敛慢。
适用:小型网络。
知识点2:OSPF协议
类型:链路状态协议。
算法:Dijkstra最短路径。
度量:代价(带宽、延迟等),无跳数限制。
特点:支持区域划分、负载均衡、认证。
适用:大型网络。
知识点3:BGP协议
类型:路径向量协议。
会话类型:
- eBGP:不同AS之间的BGP会话。
- iBGP:同一AS内部不同BGP路由器之间的会话。
四种报文:
- OPEN:建立对等体关系。
- UPDATE:通告/撤销路由。
- KEEPALIVE:周期性确认连通性。
- NOTIFICATION:报告错误。
选路原则(无策略时):优先AS路径最短。
知识点4:TTL
作用:防止分组在网络中无限循环。
规则:每经过一个路由器减1,减到0丢弃。
计算:初始TTL ≥ 路径最大跳数 + 1。
总结
| 题号 | 科目 | 分值 | 核心知识点 |
|---|---|---|---|
| 41 | 数据结构 | 13 | 拓扑排序唯一性判定 |
| 42 | 数据结构 | 10 | 二次探测法散列表 |
| 43 | 计算机组成 | 13 | RISC指令格式与数据通路 |
| 44 | 计算机组成 | 10 | C语句底层实现与存储管理 |
| 45 | 操作系统 | 7 | 页式虚拟存储地址转换 |
| 46 | 操作系统 | 8 | 进程同步与互斥信号量 |
| 47 | 计算机网络 | 9 | RIP/OSPF/BGP路由协议 |
命题特点:
- 数据结构侧重算法设计与分析(拓扑排序、散列查找)。
- 计算机组成侧重指令系统与存储系统(RISC、页式管理)。
- 操作系统侧重内存管理与进程同步(地址转换、信号量)。
- 计算机网络侧重路由协议(RIP、OSPF、BGP的对比与选择)。