|
前面学的快速排序,体现了分治的思想,但是不够典型,而归并排序则是非常典型的分治策略。归并的总体思想是先将数组分割,再分割...分割到一个元素,然后再两两归并排序,做到局部有序,不断地归并,直到数组又被全部合起来。 排序步骤大致如下: - 将长度为 n 的数组分割成为 n/2 的两个子数组。
- 子数组也不断分割成为更小的子数组,直到不能分割。
- 最小子数组之间开始两两合并,合并之后的结果再合并。合并的时候可以申请一个临时空间,利用两个索引指针比较的方式,将两个子数组的结果合并到临时数组中去。
- 循环 3 步骤,直到合并成为长度为 n 的已经排序的数组。
归并排序,分别用汇编语言,C语言,C++,java,python编写出来
当然!以下是归并排序算法的示例代码,分别使用汇编语言、C语言、C++、Java和Python编写:
1. 汇编语言(x86汇编):
- assembly
- section .data
- array db 64, 25, 12, 22, 11
- length equ $ - array
- section .text
- global _start
- _start:
- mov ecx, length
- dec ecx
- mov esi, 0
- mov edi, ecx
- call merge_sort
- ; 输出排序后的数组
- mov ecx, length
- mov esi, 0
- print_loop:
- movzx eax, byte [array + esi]
- add eax, '0'
- push eax
- push msg_digit
- call printf
- add esp, 8
- inc esi
- loop print_loop
- ; 退出程序
- mov eax, 1
- xor ebx, ebx
- int 0x80
- section .data
- msg_digit db "%c ", 0
- section .text
- extern printf, malloc, free
- merge_sort:
- push ebp
- mov ebp, esp
- sub esp, 4
- mov eax, edi
- sub eax, esi
- cmp eax, 1
- jle end_merge_sort
- mov eax, edi
- add eax, esi
- shr eax, 1
- push eax
- mov eax, edi
- sub eax, esi
- push eax
- call merge_sort
- add esp, 8
- push eax
- mov eax, edi
- add eax, esi
- shr eax, 1
- push eax
- mov eax, edi
- sub eax, esi
- push eax
- call merge_sort
- add esp, 8
- push edi
- push esi
- push edi
- sub edi, esi
- push edi
- call merge
- add esp, 16
- pop ebp
- end_merge_sort:
- ret
- merge:
- push ebp
- mov ebp, esp
- sub esp, 8
- mov eax, [ebp + 8]
- mov ecx, [ebp + 12]
- mov edx, ecx
- sub edx, eax
- mov esi, eax
- mov edi, ecx
- lea edi, [edi + 1]
- shl edi, 2
- push edi
- call malloc
- add esp, 4
- mov ebx, eax
- mov edi, eax
- mov ecx, edx
- shl ecx, 2
- rep movsd
- mov eax, [ebp + 8]
- mov ecx, [ebp + 12]
- mov edx, [ebp + 16]
- lea esi, [eax * 4 + array]
- lea edi, [edx * 4 + array]
- mov ebx, eax
- mov ebp, ecx
- merge_loop:
- cmp eax, ecx
- jge copy_remaining
- mov edx, [esi]
- cmp edx, [edi]
- jle copy_from_left
- mov edx, [edi]
- mov [esi], edx
- add edi, 4
- copy_from_left:
- add esi, 4
- inc eax
- jmp merge_loop
- copy_remaining:
-
复制代码 mov ecx, ebp
sub ecx, ebx
lea esi, [ebx * 4 + array]
lea edi, [edx * 4 + array]
shl ecx, 2
rep movsd
mov eax, ebx
shl eax, 2
add eax, array
push eax
call free
add esp, 4
pop ebp
ret
2. C语言:
- #include <stdio.h>
- #include <stdlib.h>
- void merge(int arr[], int left, int mid, int right) {
- int n1 = mid - left + 1;
- int n2 = right - mid;
- int *L = (int *)malloc(n1 * sizeof(int));
- int *R = (int *)malloc(n2 * sizeof(int));
- for (int i = 0; i < n1; i++) {
- L[i] = arr[left + i];
- }
- for (int j = 0; j < n2; j++) {
- R[j] = arr[mid + 1 + j];
- }
- int i = 0, j = 0, k = left;
- while (i < n1 && j < n2) {
- if (L[i] <= R[j]) {
- arr[k] = L[i];
- i++;
- } else {
- arr[k] = R[j];
- j++;
- }
- k++;
- }
- while (i < n1) {
- arr[k] = L[i];
- i++;
- k++;
- }
- while (j < n2) {
- arr[k] = R[j];
- j++;
- k++;
- }
- free(L);
- free(R);
- }
- void mergeSort(int arr[], int left, int right) {
- if (left < right) {
- int mid = left + (right - left) / 2;
- mergeSort(arr, left, mid);
- mergeSort(arr, mid + 1, right);
- merge(arr, left, mid, right);
- }
- }
复制代码 int main() {
int arr[] = {64, 25, 12, 22, 11};
int n = sizeof(arr) / sizeof(arr[0]);
mergeSort(arr, 0, n - 1);
printf("Sorted array: ");
for (int i = 0; i < n; i++) {
printf("%d ", arr);
}
printf("\n");
return 0;
}
3. C++:
- #include <iostream>
- using namespace std;
- void merge(int arr[], int left, int mid, int right) {
- int n1 = mid - left + 1;
- int n2 = right - mid;
- int L[n1], R[n2];
- for (int i = 0; i < n1; i++) {
- L[i] = arr[left + i];
- }
- for (int j = 0; j < n2; j++) {
- R[j] = arr[mid + 1 + j];
- }
- int i = 0, j = 0, k = left;
- while (i < n1 && j < n2) {
- if (L[i] <= R[j]) {
- arr[k] = L[i];
- i++;
- } else {
- arr[k] = R[j];
- j++;
- }
- k++;
- }
- while (i < n1) {
- arr[k] = L[i];
- i++;
- k++;
- }
- while (j < n2) {
- arr[k] = R[j];
- j++;
- k++;
- }
- }
- void mergeSort(int arr[], int left, int right) {
- if (left < right) {
- int mid = left + (right - left) / 2;
- mergeSort(arr, left, mid);
- mergeSort(arr, mid + 1, right);
- merge(arr, left, mid, right);
- }
- }
复制代码 int main() {
int arr[] = {64, 25, 12, 22, 11};
int n = sizeof(arr) / sizeof(arr[0]);
mergeSort(arr, 0, n - 1);
cout << "Sorted array: ";
for (int i = 0; i < n; i++) {
cout << arr << " ";
}
cout << endl;
return 0;
}
4. Java:
- public class MergeSort {
- public static void merge(int[] arr, int left, int mid, int right) {
- int n1 = mid - left + 1;
- int n2 = right - mid;
- int[] L = new int[n1];
- int[] R = new int[n2];
- for (int i = 0; i < n1; i++) {
- L[i] = arr[left + i];
- }
- for (int j = 0; j < n2; j++) {
- R[j] = arr[mid + 1 + j];
- }
- int i = 0, j = 0, k = left;
- while (i < n1 && j < n2) {
- if (L[i] <= R[j]) {
- arr[k] = L[i];
- i++;
- } else {
- arr[k] = R[j];
- j++;
- }
- k++;
- }
- while (i < n1) {
- arr[k] = L[i];
- i++;
- k++;
- }
- while (j < n2) {
- arr[k] = R[j];
- j++;
- k++;
- }
- }
- public static void mergeSort(int[] arr, int left, int right) {
- if (left < right) {
- int mid = (left + right) / 2;
- mergeSort(arr, left, mid);
- mergeSort(arr, mid + 1, right);
- merge(arr, left, mid, right);
- }
- }
-
- }
复制代码 public static void main(String[] args) {
int[] arr = { 64, 25, 12, 22, 11 };
mergeSort(arr, 0, arr.length - 1);
System.out.println("Sorted array:");
for (int num : arr) {
System.out.print(num + " ");
}
}
5.Python代码示例:
- def merge(arr, left, mid, right):
- n1 = mid - left + 1
- n2 = right - mid
- L = arr[left:mid+1]
- R = arr[mid+1:right+1]
- i = j = 0
- k = left
- while i < n1 and j < n2:
- if L[i] <= R[j]:
- arr[k] = L[i]
- i += 1
- else:
- arr[k] = R[j]
- j += 1
- k += 1
- while i < n1:
- arr[k] = L[i]
- i += 1
- k += 1
- while j < n2:
- arr[k] = R[j]
- j += 1
- k += 1
- def mergeSort(arr, left, right):
- if left < right:
- mid = (left + right) // 2
- mergeSort(arr, left, mid)
- mergeSort(arr, mid + 1, right)
- merge(arr, left, mid, right)
复制代码 arr = [64, 25, 12, 22, 11]
mergeSort(arr, 0, len(arr) - 1)
print("Sorted array:")
print(arr)
这些代码示例演示了如何编写归并排序算法。您可以根据需要运行这些代码,并查看排序后的结果。
|
|