一、实验内容
在 buf 缓冲区中存放有 50 个字节数据(无符号数),编写程序将这些数据由小到大排序,排序后的数据仍放在该区域中。具体功能如下:
(1)原始数据在源程序中由定义给出;
(2)在屏幕上先显示排序前的数据(十六进制),数据以每行 10 个的格式显示在屏幕上,数据与数据间用空格分开;
(3)完成排序;
(4)在屏幕上显示排序后的数据(十六进制),数据以每行 10 个的格式显示在屏幕上,数据与数据间用空格分开;
如果数据个数变为 60 或 78 等的取值时,程序代码部分无需修改。
二、子程序调用图
三、算法思想
采用经典冒泡排序方法,重复扫描要排序的元素列,依次比较两个相邻的元素,完成元素列的升序或降序排列。设数据个数为n,总共需要排序n-1趟,第i趟排序做关键字两两比较的次数为n-i,所以整体运行总的平均时间复杂度为 Q ( n 2 ) Q(n^{2}) Q(n2)。
四、运行结果截图
- 在BUF缓冲区预置50个字节数据,排序结果如下:
- 在BUF缓冲区预置了78个字节数据,排序结果如下:
五、程序源码
DATA SEGMENT
INPUT1 DB "Pre-sort data: ",'$'
INPUT2 DB "Sorted data: ",'$'
BUF DB "8D 89 1A 65 3C 01 34 6A 82 9F "
DB "8C 49 29 35 3E 11 64 66 F2 FF "
DB "ED 39 EA A5 CC 51 3D 6E 22 99 "
DB "5D F9 BA 6B 39 08 B4 EA 82 6F "
DB "AD A9 AA 22 FC F1 ED EE 12 09 "
DB "0D E9 0A 0B 49 28 24 2A A2 AF "
DB "CD C9 CA DB D9 18 04 9A 82 8F "
DB "64 8E 77 24 98 00 6A 12 ",'$' ;BUF缓冲区中预置了78个字节数据
LENGTH DW 0
NUM DW 0
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START:MOV AX,DATA
MOV DS,AX
CALL COUNT_STRING ;计数BUF缓冲区存放数据的个数
LEA DX, INPUT1 ;打印提示输出排序前数据
MOV AH, 09H
INT 21H
CALL LINE_BREAK
CALL OUTPUT_DATA ;输出排序前数据
CALL LINE_BREAK
LEA DX, INPUT2 ;打印提示输出排序后数据
MOV AH, 09H
INT 21H
CALL LINE_BREAK
CALL SORT_DATA ;去排序
CALL OUTPUT_DATA ;输出排序后结果
MOV AH,4CH
INT 21H
;----------------子程序-----------------
;-------------字符串计数器--------------
COUNT_STRING PROC
PUSH CX
LEA SI,BUF ;装载字符串指针
MOV CX,0 ;设置计数器初值
TST:CMP BYTE PTR[SI],'$' ;比较
JE DONE ;字符串结束,转向DONE保存结果
INC SI ;修改指针
INC CX ;计数
JMP TST ;转向TST,继续循环
DONE:MOV LENGTH,CX ;保存字符串长度
MOV AX,CX
MOV CX,3
DIV CX
MOV NUM,AX ;保存数据个数
POP CX
RET
COUNT_STRING ENDP
;---------------回车换行---------------
LINE_BREAK PROC
MOV DL,0DH ;显示回车符
MOV AH,2
INT 21H
MOV DL,0AH ;显示换行符
MOV AH,2
INT 21H
RET
LINE_BREAK ENDP
;------------循环输出数据------------
OUTPUT_DATA PROC
PUSH CX
XOR BL,BL
LEA SI,BUF
MOV CX,LENGTH
OUTPUT:MOV DL,[SI] ;循环输出学生信息
MOV AH,02H
INT 21H
INC SI
INC BL
CMP BL,30
JNZ NEXT
CALL LINE_BREAK
XOR BL,BL
NEXT: LOOP OUTPUT
POP CX
RET
OUTPUT_DATA ENDP
;----------从小到大排序-----------
SORT_DATA PROC
PUSH AX
XOR AX,AX
MOV CX,NUM
SUB CX,1 ;冒泡排序总共要跑的趟数
SORT: LEA SI,BUF
MOV DI,SI ;找到第一个数据的第一位字符
PUSH CX
INC AX
MOV CX,NUM
SUB CX,AX ;每一趟排序中两两比较的次数
COUNT:
MOV DX,2
SUB DI,1
ADD DI,3
N: DEC DX
CMP DX,0
SUB DI,3
ADD DI,1
JE THEN
MOV BL,BYTE PTR[DI] ;前一个数据
ADD DI,3 ;后一个数据
CMP BL,BYTE PTR[DI] ;两个数据的对应位比较
JE N
JL THEN
CALL EXCHANGE ;字符串交换
THEN: SUB DI,1
ADD DI,DX
LOOP COUNT
POP CX
LOOP SORT
POP AX
RET
SORT_DATA ENDP
;-----------排序字符串交换-----------
EXCHANGE PROC
PUSH DI
PUSH CX
MOV CX,2
SUB DI,4
ADD DI,DX
L2: MOV BH,BYTE PTR[DI] ;前一个数据
ADD DI,3
MOV BL,BYTE PTR[DI] ;后一个数据
MOV BYTE PTR[DI],BH
SUB DI,3
MOV BYTE PTR[DI],BL
INC DI ;数据的第二位
LOOP L2
POP CX
POP DI
RET
EXCHANGE ENDP
CODE ENDS
END START