📄 dfsl.asm
字号:
;图的深度优先遍历算法(利用邻接表)。
STACK EQU 1FH ;用户堆栈所在页面。
BOTTOM EQU 00H ;用户堆栈栈底单元。
TOP DATA 3DH ;用户堆栈栈顶指针。
GRAPH EQU 20H ;图存放的页面(邻接表起点为页面起点)。
OUT EQU 21H ;被访问顶点信息输出存放页面。
NODE EQU 30H ;顶点信息存放起点。
FG EQU 40H ;访问标志存放起点。
D EQU 05H ;邻接子表长度。
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,#4AH
COPY: CLR A
MOVC A,@A+DPTR
MOVX @R0,A
INC DPTR
INC R0
DJNZ R2,COPY
MOV P2,#GRAPH;指向图的存放页面。
MOV R0,#NODE
MOVX A,@R0 ;读取图的有效顶点总数。
JZ STOP ;如果是空图,则结束访问。
INC A
MOV N,A ;保存顶点总数加一。
MOV K,#1 ;从编号为1的顶点开始访问。
MOV SP,#5FH ;设置足够大的系统堆栈空间。
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,#NODE
MOV DPH,#OUT;指向输出存放顶点信息的片外RAM页面。
MOV DPL,#0
MOVX A,@R0 ;读取图的有效顶点总数。
MOVX @DPTR,A ;存放到输出区的00H单元。
INC DPTR ;指向输出区第一个存放位置。
MOV R7,A
MOV R0,#FG ;初始化访问标志。
INC R0
CLRF: CLR A
MOVX @R0,A
INC R0
DJNZ R7,CLRF
LCALL SETNULL ;初始化用户堆栈。
MOV A,K ;取访问起点编号。
LCALL DFSL ;从起点出发,调用深度优先搜索遍历算法。
INC K ;换一个顶点作为访问开始顶点。
MOV A,K
CJNE A,N,TEST1;测试完所有顶点。
STOP: LJMP STOP
;出发点为1时的遍历顺序:ABCDEFGHI
;出发点为2时的遍历顺序:BAHGEDCFI
;出发点为3时的遍历顺序:CBAHGEDFI
;出发点为4时的遍历顺序:DCBAHGEFI
;出发点为5时的遍历顺序:EDCBAHGFI
;出发点为6时的遍历顺序:FCBAHGEDI
;出发点为7时的遍历顺序:GEDBCAHIF
;出发点为8时的遍历顺序:HABCDEFGI
;出发点为9时的遍历顺序:IBAHGEDCF
DFSL: MOV R2,A ;保存当前顶点编号。
ADD A,#NODE
MOV R0,A
MOVX A,@R0 ;读取当前顶点信息。
MOVX @DPTR,A ;输出顶点信息,完成访问的目的。
INC DPTR ;调整输出指针。
MOV A,R2
ADD A,#FG
MOV R0,A ;指向该顶点标志。
MOV A,#0FFH
MOVX @R0,A ;设置已访问标志。
MOV A,R2 ;计算邻接子表的起始地址。
DEC A
MOV B,#D
MUL AB
MOV R1,A
SEARCH: MOVX A,@R1 ;读取邻接子表内容。
JZ DFSEND ;邻接子表结束,访问完毕。
MOV R3,A
ADD A,#FG
MOV R0,A
MOVX A,@R0 ;读取相邻顶点的访问标志。
JNZ SEAR1 ;已经访问过,继续读取下一单元。
MOV A,R1 ;尚未访问,准备进行递归调用。
LCALL DPUSH ;将邻接子表当前位置压入用户堆栈。
MOV A,R3 ;取出相邻顶点的编号。
LCALL DFSL ;然后按深度优先遍历算法访问该顶点。
LCALL DPOP ;取出保存的邻接子表的当前位置。
MOV R1,A
SEAR1: INC R1
LJMP SEARCH ;继续读取邻接子表中的下一单元。
DFSEND: RET ;返回。
SETNULL:MOV A,#BOTTOM ;初始化空栈,取栈底单元位置。
MOV TOP,A ;使栈顶指针指向栈底。
RET ;设置好空栈。
DPUSH: INC TOP ;新栈顶。
PUSH DPH
PUSH DPL
MOV DPH,#STACK ;取堆栈所在页面。
MOV DPL,TOP ;取栈顶单元位置。
MOVX @DPTR,A ;数据压入栈顶。
POP DPL
POP DPH
RET ;结束。
DPOP: PUSH DPH
PUSH DPL
MOV DPH,#STACK ;取堆栈所在页面。
MOV DPL,TOP ;取栈顶单元。
MOVX A,@DPTR ;取出栈顶元素。
DEC TOP ;指向新的栈顶。
POP DPL
POP DPH
RET ;结束。
;2000H: 02 08 00 00 00
;2005H: 01 03 09 00 00
;200AH: 02 04 06 00 00
;200FH: 03 05 00 00 00
;2014H: 04 06 07 00 00
;2019H: 03 05 07 09 00
;201EH: 05 06 08 00 00
;2023H: 01 07 09 00 00
;2028H: 02 06 08 00 00
;2030H: 09 41 42 43 44 45 46 47 48 49
;2040H: 00 00 00 00 00 00 00 00 00 00
GRA: DB 02H,08H,00H,00H ;邻接表。
DB 00H,01H,03H,09H
DB 00H,00H,02H,04H
DB 06H,00H,00H,03H
DB 05H,00H,00H,00H
DB 04H,06H,07H,00H
DB 00H,03H,05H,07H
DB 09H,00H,05H,06H
DB 08H,00H,00H,01H
DB 07H,09H,00H,00H
DB 02H,06H,08H,00H
DB 00H,00H,00H,00H
DB 09H,41H,42H,43H
DB 44H,45H,46H,47H
DB 48H,49H,00H,00H
DB 00H,00H,00H,00H
DB 00H,00H,00H,00H
DB 00H,00H,00H,00H
DB 00H,00H
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -