📄 minghuan.asm
字号:
TITLE MINGHUAN (EXE) ;文件名minghuan
.MODEL SMALL
.STACK 64
.DATA
;=====================================================================================
MYDATA DB 31 DUP(0,0,0)
NEWLINE1 DB 0AH,0DH,'---','$'
NEWLINE2 DB 0AH,0DH,'$'
INROOT DB 'Please input the root:',0DH,0AH,'$' ;输入根节点
INLCHILD DB '---have a leftchild?(If it no leftchild,please press ENTER)',0DH,0AH,'$'
;是否有左子树,无则恩ENTER
INRCHILD DB '---have a rightchild?(If it no rightchild,please press ENTER)',0DH,0AH,'$'
;是否有右子树,无则恩ENTER
FIRSTTR DB 'The first root taraversing:',0DH,0AH,'$' ;前序遍历
MIDRRLE DB 'The middle root taraversing:',0DH,0AH,'$' ;中序遍历
LASTTR DB 'The last root taraversing:',0DH,0AH,'$' ;后序遍历
SELECTOUT DB 'F is first output,M is midr output, L is last output,A is all output',0DH,0AH,'$'
;选择输出方式
REINPUT DB 0AH,0DH,'Please reinput in [F],[M],[L],[A]','$'
EMPTYTREE DB 0AH,0DH,'This is empty tree',0AH,0DH,'$' ;提示是个空树
INOVER DB 0DH,0AH,'The input is over!','$' ;输入结束
;=====================================================================================
.CODE
MAIN PROC FAR
MOV AX,@DATA ;初始化
MOV DS,AX
MOV DX,OFFSET INROOT
MOV AX,0900H ;要求显示 INROOT字符窜
INT 21H
MOV SI,OFFSET MYDATA ;SI初始化指向根节点
SUB CX,CX ;CX清零
MOV AX,0100H ;请求输入字符并保存到AX中
INT 21H
CMP AL,0DH ;判断输入的是否是ENTER
JZ EXIT1 ;是,则退出
ADD CX,3 ;计数器加3
CALL INPUTROOT ;跳转到INPUTROOT
CALL SELECTOUTPUT ;选择输出方式
JMP EXIT2
EXIT1:
MOV DX,OFFSET EMPTYTREE ;打印字符窜
MOV AX,0900H ;提示是个空树
INT 21H
EXIT2:
MOV AX,4C00H ;推出程序
INT 21H
MAIN ENDP
;======================================================================================
;=======================输出段
SELECTOUTPUT PROC NEAR
MOV AX,0900H
MOV DX,OFFSET INOVER ;输入结束
INT 21H
REINPUTCHAR:
CALL NEWLINES
MOV DX,OFFSET SELECTOUT
MOV AX,0900H
INT 21H ;打印选择输出方式的字符串
MOV AX,0100H
INT 21H
MOV DL,'F' ;前序遍历输出
CMP AL,DL
JZ FIRSTCALL
MOV DL,'M' ;中序遍历输出
CMP AL,DL
JZ MIDRCALL
MOV DL,'L' ;后序遍历输出
CMP AL,DL
JZ LASTCALL
MOV DL,'A' ;三种方式全部都打印
CMP AL,DL
JZ ALLCALL
MOV DX,OFFSET REINPUT ;重新输入
MOV AX,0900H
INT 21H
CALL REINPUTCHAR
;=============================
FIRSTCALL:
CALL NEWLINES
CALL FIRST ;调用前序输出方法
JMP EXIT7
MIDRCALL: ;调用中序输出方法
CALL NEWLINES
MOV DX,OFFSET MIDRRLE
MOV AX,0900H
INT 21H
MOV SI,OFFSET MYDATA
MOV CX,3
CALL MIDR
JMP EXIT7
LASTCALL: ;调用后序输出方法
CALL NEWLINES
MOV DX,OFFSET LASTTR
MOV AX,0900H
INT 21H
MOV SI,OFFSET MYDATA
MOV CX,3
CALL LAST
JMP EXIT7
ALLCALL: ;三种输出方式
CALL ALLOUTPUT
EXIT7:
MOV AX,4C00H ;推出程序
INT 21H
SELECTOUTPUT ENDP
;======================================================================================
;=======================全部输出段
ALLOUTPUT PROC NEAR
CALL NEWLINES
CALL FIRST ;前序遍历
CALL NEWLINES
MOV AX,0900H ;输出中序遍历提示符
MOV DX,OFFSET MIDRRLE
INT 21H
MOV SI,OFFSET MYDATA
MOV CX,3
CALL MIDR ;中序遍历输出
CALL NEWLINES
MOV DX,OFFSET LASTTR
MOV AX,0900H
INT 21H
MOV SI,OFFSET MYDATA
MOV CX,3
CALL LAST ;后序遍历输出
RET
ALLOUTPUT ENDP
;======================================================================================
NEWLINES PROC NEAR
MOV DX,OFFSET NEWLINE2 ;换行
MOV AX,0900H
INT 21H
RET
NEWLINES ENDP
;=======================================================================================
INPUTROOT PROC NEAR
PUSH AX
PUSH DX
CMP CX,93 ;判断有无最后一个子树
JZ QUIT1 ;输入结束
MOV [SI],AL ;保存从键盘输入的字符
CALL LCHILD ;输入左子树
CALL RCHILD ;输入右子树
POP DX
POP AX
RET
QUIT1:
CALL SELECTOUTPUT
INT 21H ;输入结束
MOV AX,4C00H ;推出程序
INT 21H
INPUTROOT ENDP
;=======================================================================================
LCHILD PROC NEAR
PUSH AX
PUSH DX
PUSH BX
MOV BX,OFFSET NEWLINE1 ;换行并输出字符串---
MOV DX,BX
MOV AX,0900H
INT 21H
MOV AX,0200H ;输出字符[SI]的值
MOV DL,[SI] ;[SI]的值
INT 21H
MOV AX,0900H ;请求输出字符窜
MOV BX,OFFSET INLCHILD ;INLCHILD
MOV DX,BX
INT 21H
MOV AX,0100H ;请求输入字符
INT 21H
CMP AL,0DH ; 判断输入的是否为ENTER
JZ BACK1 ;是,则退出
ADD BYTE PTR[SI+1],1 ; 1 保存到[SI+1]的地址里
PUSH SI ;保存
MOV SI,OFFSET MYDATA ;初始化SI
ADD SI,CX ;指向下一个节点
ADD CX,3 ;计数器加3
CALL INPUTROOT ;递归
POP SI
BACK1:
POP BX
POP DX
POP AX
RET
LCHILD ENDP
;=======================================================================================
RCHILD PROC NEAR
PUSH AX
PUSH DX
PUSH BX
MOV BX,OFFSET NEWLINE1 ;换行并输出字符串---
MOV DX,BX
MOV AX,0900H
INT 21H
MOV AX,0200H ;输出字符[SI]的值
MOV DL,[SI] ;[SI]的值
INT 21H
MOV AX,0900H ;请求输出字符窜
MOV BX,OFFSET INRCHILD ;INRCHILD
MOV DX,BX ;
INT 21H
MOV AX,0100H ;请求输入字符
INT 21H
CMP AL,0DH ; 判断输入的是否为ENTER
JZ BACK2 ;是,则退出
ADD BYTE PTR[SI+2],1 ; 1 保存到[SI+2]的地址里
PUSH SI ; 保存
MOV SI,OFFSET MYDATA ;初始化SI
ADD SI,CX ;指向下一个节点
ADD CX,3 ;计数器加3
CALL INPUTROOT ;递归
POP SI
BACK2:
SUB SI,3 ;如果没有右字树,则返回到当前的根节点
POP BX
POP DX
POP AX
RET
RCHILD ENDP
;========================================================================================
;===========================================前序遍历输出
FIRST PROC NEAR
PUSH AX
PUSH DX
MOV AX,0900H ;显示FIRSTTR字符串
MOV DX,OFFSET FIRSTTR
INT 21H
MOV SI,OFFSET MYDATA ;让SI指向根节点
LOOPP:
MOV DL,[SI] ;打印根节点
MOV AX,0200H
INT 21H
ADD SI,3 ;指向下一个节点
CMP BYTE PTR[SI],0 ;判断下一个节点是否为空
JZ EXIT8
JMP LOOPP ;递归
EXIT8:
POP DX
POP AX
RET
FIRST ENDP
;=======================================================================================
;==============================================中序遍历输出
MIDR PROC NEAR
PUSH AX
PUSH DX
CALL MIDRL ;判断有无左孩子
MOV AX,0200H ;打印根节点
MOV DL,[SI]
INT 21H
CALL MIDRR ;判断有无右孩子
POP DX
POP AX
RET
MIDR ENDP
;--------------------------------------------
MIDRL PROC NEAR
PUSH AX
PUSH DX
CMP BYTE PTR[SI+1],0 ;判断有无左孩子
JZ EXIT3
PUSH SI ;保存现场
MOV SI,OFFSET MYDATA ;初始化SI
ADD SI,CX ;指向下一个孩子
ADD CX,3 ;计数器加3
CALL MIDR ;递归
POP SI
EXIT3:
POP DX
POP AX
RET
MIDRL ENDP
;----------------------------------------------
MIDRR PROC NEAR
PUSH AX
PUSH DX
CMP BYTE PTR[SI+2],0 ;判断有无右孩子
JZ EXIT4
PUSH SI ;保存现场
MOV SI,OFFSET MYDATA ;初始化SI
ADD SI,CX ;指向下一个孩子
ADD CX,3 ;计数器加3
CALL MIDR ;递归
POP SI
EXIT4:
SUB SI,3 ;回到根节点的位置
POP DX
POP AX
RET
MIDRR ENDP
;=======================================================================================
LAST PROC NEAR
PUSH AX
PUSH DX
CALL LASTL ;判断有无左孩子
CALL LASTR ;判断有无右孩子
MOV AX,0200H ;打印根节点
MOV DL,[SI]
INT 21H
SUB SI,3
POP DX
POP AX
RET
LAST ENDP
;--------------------------------------------
LASTL PROC NEAR
PUSH AX
PUSH DX
CMP BYTE PTR[SI+1],0 ;判断有无左孩子
JZ EXIT5
PUSH SI ;保存现场
MOV SI,OFFSET MYDATA ;初始化SI
ADD SI,CX ;指向下一个孩子
ADD CX,3 ;计数器加3
CALL LAST ;递归
POP SI
EXIT5:
POP DX
POP AX
RET
LASTL ENDP
;----------------------------------------------
LASTR PROC NEAR
PUSH AX
PUSH DX
CMP BYTE PTR[SI+2],0 ;判断有无右孩子
JZ EXIT6
PUSH SI ;保存现场
MOV SI,OFFSET MYDATA ;初始化SI
ADD SI,CX ;指向下一个孩子
ADD CX,3 ;计数器加3
CALL LAST ;递归
POP SI
EXIT6:
POP DX
POP AX
RET
LASTR ENDP
;========================================================================================
END MAIN
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -