【汇编语言实战】对给定的数组实现堆排序

本文详细介绍了如何使用C语言实现堆排序算法,包括交换数组元素值、调整堆以保持最大堆性质以及堆排序过程。同时提供了汇编语言版本的部分代码片段,展示了整个技术流程。

C语言描述:

#include <stdio.h>

// 交换数组中两个元素的值
void swap(int* a, int* b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

// 调整堆,使以root为根节点的堆满足最大堆性质
void maxHeapify(int arr[], int n, int root) {
    int largest = root;     // 初始化最大值索引为根节点
    int left = 2 * root + 1;    // 左子节点索引
    int right = 2 * root + 2;   // 右子节点索引
    
    // 如果左子节点存在且大于根节点,则更新最大值索引为左子节点
    if (left < n && arr[left] > arr[largest])
        largest = left;
    
    // 如果右子节点存在且大于当前最大值,则更新最大值索引为右子节点
    if (right < n && arr[right] > arr[largest])
        largest = right;
    
    // 如果最大值索引不是根节点,则交换根节点与最大值,并递归调整子树
    if (largest != root) {
        swap(&arr[root], &arr[largest]);
        maxHeapify(arr, n, largest);
    }
}

// 构建最大堆
void buildMaxHeap(int arr[], int n) {
    // 从最后一个非叶子节点开始,依次向前调整堆
    for (int i = n / 2 - 1; i >= 0; i--) {
        maxHeapify(arr, n, i);
    }
}

// 堆排序
void heapSort(int arr[], int n) {
    // 构建最大堆
    buildMaxHeap(arr, n);
    
    // 从最后一个元素开始,依次将最大值交换至数组末尾,并调整堆
    for (int i = n - 1; i >= 0; i--) {
        swap(&arr[0], &arr[i]);   // 将当前最大值交换至数组末尾
        maxHeapify(arr, i, 0);     // 调整剩余元素为最大堆
    }
}

int main() {
    int arr[] = {3, 1, 5, 7, 2, 4, 9, 6, 10, 8};
    int n = sizeof(arr) / sizeof(arr[0]);

    
    heapSort(arr, n);
    
    printf("堆排序后数组:");
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    
    return 0;
}

汇编语言:

include irvine32.inc
.data
	arr dd 3,1,5,7,2,4,9,6,10,8
	len dd ($-arr)/4
	two dd 2
	msg1 db ' ',0
	msg2 db ' ',0
	msg3 db ' ',0
.code
print proc
	push ebp
	mov ebp,esp
	pushad
	mov esi,0
	mov ebx,[ebp+8]
again:
	cmp esi,[ebp+12]
	jge final
	mov eax,[ebx+4*esi]
	call writeint
	mov edx,offset msg1
	call writestring
	add esi,1
	jmp again
final:
	popad
	pop ebp
	ret 8
print endp
HeapAdjust proc
	push ebp
	mov ebp,esp
	pushad
 
	mov esi,[ebp+8]
	mov ebx,[ebp+12]
	mov ecx,[esi+4*ebx]
 
	mov eax,ebx
	mul two
	add eax,1
 
again:
 
	cmp eax,[ebp+16]
	jge final
	mov edx,eax
	add edx,1
	cmp edx,[ebp+16]
	jge next1
	mov edi,[esi+4*eax]
	cmp edi,[esi+4*edx]
	jge next1
	add eax,1
next1: 
	mov edx,[esi+4*eax]
	cmp [esi+4*ebx],edx
	jge final
	mov [esi+4*ebx],edx
	mov ebx,eax
	mov eax,ebx
	shl eax,1
	add eax,1
	mov [esi+4*ebx],ecx
	jmp again
 
final:
	popad
	pop ebp
	ret 12
HeapAdjust endp
 
BuildingHeap proc
	push ebp
	mov ebp,esp
	pushad
	mov eax,[ebp+12]
	sub eax,1
	mov edx,0
	div two
again:
 
	cmp eax,0
	jl final
	push dword ptr[ebp+12]
	push eax
	push dword ptr[ebp+8]
	call HeapAdjust
	sub eax,1
	jmp again
final:
	popad
	pop ebp
	ret 8
BuildingHeap endp
 
HeapSort proc
	push ebp
	mov ebp,esp
	pushad
	push dword ptr[ebp+12]
	push dword ptr[ebp+8]
	call BuildingHeap
	mov edx,[ebp+8]
	mov esi,[ebp+12]
	sub esi,1
again:
 
	cmp esi,0
	jle final
	mov edi,0
	mov ebx,[edx+4*esi]
	mov ecx,[edx+4*edi]
	mov [edx+4*esi],ecx
	mov [edx+4*edi],ebx
	push esi
	push edi
	push dword ptr[ebp+8]
	call HeapAdjust
	sub esi,1
	jmp again
final:
	popad
	pop ebp
	ret 8
HeapSort endp
 
main proc
	mov edx,offset msg2
	call writestring
	push len
	push offset arr
	call print
        call crlf 
	push len
	push offset arr
	call HeapSort
	mov edx,offset msg3
	call writestring
	push len
	push offset arr
	call print
	exit
main endp
end main

运行结果:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秋说

感谢打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值