📄 bfs.asm
字号:
;图的广度优先遍历算法(利用邻接矩阵)。
GRAPH EQU 20H ;图存放的片外RAM页面(顶点总数不超过15)。
OUT EQU 21H ;被访问顶点信息输出存放页面。
QUEUE EQU 1FH ;循环队列存储页面。
F DATA 3CH ;队首指针的存放单元。
R DATA 3DH ;队尾指针的存放单元。
N DATA 3EH ;顶点总数加一存放单元。
K DATA 3FH ;访问起点编号存放单元。
ORG 0000H
LJMP TEST
ORG 100H
TEST: MOV SP,#5FH ;设置足够大的系统堆栈空间。
MOV DPTR,#GRA;将邻接矩阵拷贝到片外RAM中。
MOV P2,#GRAPH
MOV R0,#0
MOV R2,#0A0H
COPY: CLR A
MOVC A,@A+DPTR
MOVX @R0,A
INC DPTR
INC R0
DJNZ R2,COPY
MOV P2,#GRAPH;指向图的存放页面。
MOV R0,#0
MOVX A,@R0 ;读取图的有效顶点总数。
JZ STOP ;如果是空图,则结束访问。
INC A
MOV N,A ;保存顶点总数加一。
MOV K,#1 ;以序号为1的顶点作为访问的开始顶点。
TEST1: MOV DPH,#OUT;指向输出存放顶点信息的片外RAM页面。
MOV DPL,#0
MOV R2,#0
CLR A
CLEAR: MOVX @DPTR,A ;初始化输出区。
INC DPTR
DJNZ R2,CLEAR
MOV P2,#GRAPH;指向图的存放页面。
MOV R0,#0
MOV DPH,#OUT;指向输出顶点信息的片外RAM页面。
MOV DPL,#0
MOVX A,@R0 ;读取图的有效顶点总数。
MOVX @DPTR,A ;存放到输出区的00H单元。
MOV R7,A ;保存图的顶点总数。
INC DPTR ;指向输出区第一个存放位置。
MOV R0,#10H ;初始化访问标志。
CLRF: CLR A
MOVX @R0,A
MOV A,#10H ;调整到下一个标志。
ADD A,R0
MOV R0,A
JNZ CLRF
LCALL SETNULL ;初始化队列为空队。
MOV A,K ;取访问起点编号。
LCALL DATAIN ;排入队列中。
LCALL BFS ;从起点出发,调用广度优先搜索遍历算法。
INC K ;换一个开始顶点。
MOV A,K
CJNE A,N,TEST1;测试完所有顶点。
STOP: LJMP STOP
;出发点为1时的遍历顺序:ABHCIGDFE
;出发点为2时的遍历顺序:BACIHDFGE
;出发点为3时的遍历顺序:CBDFAIEGH
;出发点为4时的遍历顺序:DCEBFGAIH
;出发点为5时的遍历顺序:EDFGCIHBA
;出发点为6时的遍历顺序:FCEGIBDHA
;出发点为7时的遍历顺序:GEFHDCIAB
;出发点为8时的遍历顺序:HAGIBEFCD
;出发点为9时的遍历顺序:IBFHACEGD
BFS: MOV A,F ;判断是否为空队。
XRL A,R
JZ BFSEND ;是空队,访问结束。
LCALL DATAOUT ;队首顶点编号出队。
MOV R0,A
MOVX A,@R0 ;读取顶点信息。
MOVX @DPTR,A ;输出到输出区。
INC DPTR
MOV A,R0 ;转换成标志的地址。
SWAP A
MOV R1,A
MOV A,#0FFH
MOVX @R1,A ;设立已访问标志。
INC R1 ;开始查邻接矩阵。
MOV A,R7
MOV R6,A
LOOP: MOVX A,@R1 ;读取邻接矩阵的元素。
JZ LOOPE ;为零,不是相邻顶点。
MOV A,R1 ;不为零,取出相邻顶点的编号。
ANL A,#0FH
MOV R2,A ;保存相邻顶点编号。
SWAP A
MOV R0,A
MOVX A,@R0 ;读取相邻顶点的访问标志。
JNZ LOOPE ;该顶点已访问(或已在队列中),跳过。
MOV A,R2
LCALL DATAIN ;尚未访问过,将其排入队列中。
MOV A,#1
MOVX @R0,A ;设置已排队标志。
LOOPE: INC R1 ;调整邻接矩阵元素指针。
DJNZ R6,LOOP ;处理完邻接矩阵的一行。
LJMP BFS ;继续处理队列中的其它顶点。
BFSEND: RET ;返回。
SETNULL:MOV A,#0FFH
MOV F,A ;使队首指针指向队列页面的最后一个单元。
MOV R,A ;使队尾指针也指向队列页面的最后一个单元。
RET ;设置好空队列。
DATAIN: PUSH DPH
PUSH DPL
INC R ;调整队尾指针。
MOV DPL,R
MOV DPH,#QUEUE
MOVX @DPTR,A ;排入队尾。
POP DPL
POP DPH
RET ;结束
DATAOUT:PUSH DPH
PUSH DPL
INC F ;调整队首指针。
MOV DPL,F
MOV DPH,#QUEUE
MOVX A,@DPTR ;取待出队数据。
POP DPL
POP DPH
RET ;结束。
;2000H: 09 41 42 43 44 45 46 47 48 49
;2010H: 00 00 01 00 00 00 00 00 01 00
;2020H: 00 01 00 01 00 00 00 00 00 01
;2030H: 00 00 01 00 01 00 01 00 00 00
;2040H: 00 00 00 01 00 01 00 00 00 00
;2050H: 00 00 00 00 01 00 01 01 00 00
;2060H: 00 00 00 01 00 01 00 01 00 01
;2070H: 00 00 00 00 00 01 01 00 01 00
;2080H: 00 01 00 00 00 00 00 01 00 01
;2090H: 00 00 01 00 00 00 01 00 01 00
GRA: DB 09H,41H,42H,43H ;邻接矩阵。
DB 44H,45H,46H,47H
DB 48H,49H,00H,00H
DB 00H,00H,00H,00H
DB 00H,00H,01H,00H
DB 00H,00H,00H,00H
DB 01H,00H,00H,00H
DB 00H,00H,00H,00H
DB 00H,01H,00H,01H
DB 00H,00H,00H,00H
DB 00H,01H,00H,00H
DB 00H,00H,00H,00H
DB 00H,00H,01H,00H
DB 01H,00H,01H,00H
DB 00H,00H,00H,00H
DB 00H,00H,00H,00H
DB 00H,00H,00H,01H
DB 00H,01H,00H,00H
DB 00H,00H,00H,00H
DB 00H,00H,00H,00H
DB 00H,00H,00H,00H
DB 01H,00H,01H,01H
DB 00H,00H,00H,00H
DB 00H,00H,00H,00H
DB 00H,00H,00H,01H
DB 00H,01H,00H,01H
DB 00H,01H,00H,00H
DB 00H,00H,00H,00H
DB 00H,00H,00H,00H
DB 00H,01H,01H,00H
DB 01H,00H,00H,00H
DB 00H,00H,00H,00H
DB 00H,01H,00H,00H
DB 00H,00H,00H,01H
DB 00H,01H,00H,00H
DB 00H,00H,00H,00H
DB 00H,00H,01H,00H
DB 00H,00H,01H,00H
DB 01H,00H,00H,00H
DB 00H,00H,00H,00H
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -