• 汇编入门之快速排序和数组遍历


    原创文章,转载请注明:汇编入门之快速排序和数组遍历  By Lucio.Yang

    1.程序内容描述

      将两个数组X、Y进行从小到大的快速排序后,将两个数组相同的元素按照从大到小的顺序输出到Z中。

    2.程序流程图

      

    3.源代码

    DATAS SEGMENT
    COUNT DW 20
    BEGINC DW 0
    X DB 4,3,5,7,9,0,3,7,8,9,5,4,5,7,1,6,3,6,1,0
    Y DB 5,9,7,3,1,6,3,5,4,0,0,1,3,7,2,5,4,5,3,1
    Z DB 20 DUP(?)
    ENT db ';',0ah,0dh,'$'
    DATAS ENDS
    
    STACKS SEGMENT
        ;此处输入堆栈段代码
    STACKS ENDS
    
    CODES SEGMENT
        ASSUME CS:CODES,DS:DATAS,SS:STACKS
    START:
        MOV AX,DATAS
        MOV DS,AX
    
        ;X排序
        MOV SI,OFFSET X
        MOV DI,OFFSET X;数组起始地址
        MOV BX,OFFSET X
        ADD BX,COUNT
        DEC BX;数组结束地址
        CALL QSORT;调用排序函数
        MOV DL,'X';输出空格
        CALL OUTPUT
        MOV DL,':';输出空格
        CALL OUTPUT
        MOV CX,COUNT
        CALL SHOW;调用输出函数
        MOV DX,OFFSET ENT;输出回车
        MOV AH,09H
        INT 21H
        
        ;Y排序
        MOV SI,OFFSET Y
        MOV DI,OFFSET Y;数组起始地址
        MOV BX,OFFSET Y
        ADD BX,COUNT
        DEC BX;数组结束地址
        CALL QSORT;调用排序函数
        MOV DL,'Y';输出空格
        CALL OUTPUT
        MOV DL,':';输出空格
        CALL OUTPUT
        MOV CX,COUNT
        CALL SHOW;调用输出函数
        MOV DX,OFFSET ENT;输出回车
        MOV AH,09H
        INT 21H
        
        ;从后向前遍历
        XOR DI,DI;X的地址增量
        ADD DI,COUNT
        DEC DI
        XOR BX,BX;Y的地址增量
        ADD BX,COUNT
        DEC BX
        XOR SI,SI;Z的地址增量
    COMPARE:
        CMP DI,BEGINC
        JE QUITC;DI<0
        CMP BX,BEGINC
        JE QUITC;BX<0
        
        MOV DH,X[DI]
        CMP DH,Y[BX]
        JE MOVEALL 
        JA MOVEX;x的元素大于y的元素,x的指针前移
        JB MOVEY
    MOVEALL:;元素相等
        MOV DH,X[DI]
        MOV Z[SI],DH;元素相同,移入Z中
        DEC DI
        DEC BX
        INC SI
        JMP COMPARE
    MOVEX:;X的指针前移
        DEC DI
        JMP COMPARE
    MOVEY:;Y的指针前移
        DEC BX
        JMP COMPARE
    QUITC:
        MOV DH,X[DI]
        CMP DH,Y[BX]
        JE MOVE
        JNE OUTPUTZ
    MOVE:
        MOV DH,X[DI]
        MOV Z[SI],DH;元素相同,移入Z中
        INC SI
    OUTPUTZ:    
        MOV CX,SI
        MOV SI,OFFSET Z
        MOV DL,'Z';输出空格
        CALL OUTPUT
        MOV DL,':';输出空格
        CALL OUTPUT
    
        CALL SHOW;调用输出函数
        MOV DL,';';输出回车
        CALL OUTPUT
        
        MOV AH,4CH
        INT 21H
    QSORT PROC NEAR;排序函数
        PUSH DI;调取左值
        PUSH BX;调取右值
        CMP DI,BX
        JNB DONE;DI>=BX
        PUSH DI;保存左值
        PUSH BX;保存右值
        CALL PARTITION;进行一趟排序,将数据分成两段,中轴地址在AX
        POP BX
        POP DI
        
        PUSH BX;保存右值
        MOV BX,AX;a[i]=key,ax中存放枢轴的地址
        DEC BX
        PUSH DI;保存左值
        PUSH BX;i-1
        CALL QSORT;Qsort(a,left,i-1);   
        
        POP BX
        POP DI
        POP BX;消除上一次
        
        MOV DI,AX
        INC DI
        PUSH DI
        PUSH BX
        CALL QSORT;Qsort(a,i+1,right);
        
        POP BX
        POP DI
    DONE:;快排结束
        POP BX
        POP DI
        RET
    QSORT   ENDP
    
    PARTITION PROC NEAR
        MOV CL,[DI];CL中存放左值,即为key
    AG: 
        CMP DI,BX;while left<right
        JNB QUIT;DI>=BX
    A:   
        CMP DI,BX;left<right
           JNB SWAP1;DI>=BX跳转  
        CMP [BX],CL;and key<=a[j]
        JB SWAP1;a[j]<=key,即找到了小数,交换到左边
        DEC BX;j--
        JMP A;while
    SWAP1:;a[i]=a[j]
        MOV CH,[BX];[di]与[bx]交换
        MOV AH,[DI]
        MOV [DI],CH
        MOV [BX],AH
    B:    
        CMP DI,BX;left<right
           JNB SWAP2;DI>=BX跳转  
        CMP [DI],CL;and key>=a[j]
        JA SWAP2;a[j]<=key,即找到了大数,交换到右边
        INC DI;i++
        JMP B
    SWAP2:;A[I]=A[J]
        MOV CH,[BX]
        MOV AH,[DI]
        MOV [DI],CH
        MOV [BX],AH
        JMP AG;一趟完成,循环
    QUIT:
        MOV AX,DI;中轴地址给Ax
        RET
    PARTITION ENDP
    
    SHOW PROC NEAR
    AG:
        XOR AL,AL
        ADD AL,[SI]
        ADD AL,'0'
        MOV DL,AL;输出数组一个数
        INC SI
        CALL OUTPUT
        MOV DL,' ';输出空格
        CALL OUTPUT
        LOOP AG;循环
        RET
    SHOW ENDP 
    
    OUTPUT PROC
        MOV AH,02
        INT 21H
        RET
    OUTPUT ENDP
    
    CODES ENDS
    END START
    View Code
  • 相关阅读:
    【Linux】Gitlab库已损坏前端显示500错误解决方法
    【linux】gitlab 的安装以及数据迁移
    【PHP】图片转换为base64,经过post传输后‘+’会变成 ‘空格’
    【Mac】解决外接显示器时无法用键盘调节音量
    【Mac】 /usr/local 文件夹权限问题
    学妹问的Spring Bean常用配置,我用最通俗易懂的讲解让她学会了
    上海月薪 1w 和家乡月薪 5000 你选择哪?
    30岁码农的一次面试经历:不委屈自己
    写4条宝贵的经验,给初入职场的你
    Java 8 Optional 良心指南,建议收藏
  • 原文地址:https://www.cnblogs.com/lucio_yz/p/4418066.html
Copyright © 2020-2023  润新知