如何基于现有数字冒泡排序汇编程序实现按成绩排序学生姓名
Hey there! Great question—let's walk through how to adapt your bubble sort to sort student names alongside their grades. The core idea is to group each student's grade and name into a fixed-length "record" so that when we sort by grades, the names stay tied to their corresponding scores. Here's a step-by-step breakdown:
Step 1: Restructure Your Data Section
Instead of a simple array of numbers, we'll define fixed-length student records where each record holds a grade (1 byte) followed by a name (we'll use a fixed length like 7 characters to keep things consistent). This ensures we can easily calculate offsets between records.
.data ; Define the length of one student record: 1 byte for grade + 7 bytes for name STUDENT_RECORD_LEN equ 8 ; Student records: [grade] + [name (7 chars, pad with spaces if needed)] students db 85, 'Alice ' ; 85 points, Alice (2 spaces to fill 7 chars) db 92, 'Bob ' ; 92 points, Bob (4 spaces to fill 7 chars) db 78, 'Charlie' ; 78 points, Charlie (exactly 7 chars) db 95, 'Diana ' ; 95 points, Diana (2 spaces) count dw 4 ; Number of students
Step 2: Modify the Bubble Sort Logic
Your original sort works for single-byte elements, but now we need to:
- Compare only the grade field of each student record.
- Swap entire student records (not just single bytes) when a grade needs to move.
- Adjust the index (
si) to jump by the full record length instead of 1 byte.
Here's the updated code:
.code mov cx, count dec cx ; Number of passes = count - 1 nextscan: mov bx, cx ; Number of comparisons per pass mov si, 0 ; Start at the first student record nextcomp: ; Grab the grade of the current student and the next student mov al, students[si] ; Current student's grade mov dl, students[si + STUDENT_RECORD_LEN] ; Next student's grade cmp al, dl jnc noswap ; If current grade >= next grade, skip swap ; Swap the entire student records (grade + name) mov di, si add di, STUDENT_RECORD_LEN ; Point DI to the next student record mov cx, STUDENT_RECORD_LEN ; Number of bytes to swap push si ; Save SI's starting position swap_byte_loop: mov al, [si] mov bl, [di] mov [si], bl mov [di], al inc si inc di loop swap_byte_loop pop si ; Restore SI to the current record's start noswap: add si, STUDENT_RECORD_LEN ; Move to the next student record dec bx jnz nextcomp ; Repeat comparisons for this pass loop nextscan ; Repeat all passes
Key Notes to Remember
- Fixed-length records are critical: Using a consistent record length makes it easy to calculate where each student's data starts and ends. If you use variable-length names, you'd need to add pointers or length fields, which complicates things for a basic program.
- Swap the whole record: When you swap grades, you have to swap the corresponding names too. The loop inside
noswaphandles this by copying each byte of the record one by one. - Sort order: The example sorts in ascending order (lowest grades first). To switch to descending order, change
jnc noswaptojc noswap(only skip swapping if the current grade is less than the next).
内容的提问来源于stack exchange,提问作者Faris Dahleh

