generated from rockbenben/LearnData
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
213 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -39,6 +39,7 @@ export default sidebar({ | |
collapsible: true, | ||
children: [ | ||
'希尔排序.md', | ||
'归并排序.md' | ||
], | ||
}, | ||
] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,212 @@ | ||
--- | ||
title: 归并排序 | ||
date: 2024-07-16 | ||
category: | ||
- 代码编程 | ||
- 算法 | ||
tag: | ||
- 算法 | ||
sticky: true | ||
star: true | ||
order: -1 | ||
--- | ||
|
||
# 归并排序 | ||
|
||
## 介绍 | ||
**归并排序**(*Merge Sort*)是一种基于分治法的排序算法。它的主要思想是将一个大的问题分解成若干个小问题来解决,然后将解决的结果合并在一起。归并排序的时间复杂度为 𝑂(𝑛log𝑛),是效率较高的排序算法之一。 | ||
|
||
## 代码 | ||
|
||
### 迭代 | ||
1. C | ||
``` | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
int min(int x, int y) | ||
{ | ||
return x < y ? x : y; | ||
} | ||
void merge_sort(int arr[], int len) | ||
{ | ||
int *a = arr; | ||
int *b = (int *)malloc(len * sizeof(int)); | ||
if (b == NULL) | ||
{ | ||
fprintf(stderr, "Memory allocation failed\n"); | ||
return; | ||
} | ||
int seg, start; | ||
for (seg = 1; seg < len; seg += seg) | ||
{ | ||
for (start = 0; start < len; start += seg + seg) | ||
{ | ||
int low = start, mid = min(start + seg, len), high = min(start + 2 * seg, len); | ||
int k = low; | ||
int start1 = low, end1 = mid; | ||
int start2 = mid, end2 = high; | ||
while (start1 < end1 && start2 < end2) | ||
b[k++] = a[start1] < a[start2] ? a[start1++] : a[start2++]; | ||
while (start1 < end1) | ||
b[k++] = a[start1++]; | ||
while (start2 < end2) | ||
b[k++] = a[start2++]; | ||
} | ||
int *temp = a; | ||
a = b; | ||
b = temp; | ||
} | ||
if (a != arr) | ||
{ | ||
for (int i = 0; i < len; i++) | ||
arr[i] = a[i]; | ||
} | ||
free(b); | ||
} | ||
int main() | ||
{ | ||
int arr[] = {22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70}; | ||
int len = sizeof(arr) / sizeof(*arr); | ||
merge_sort(arr, len); | ||
for (int i = 0; i < len; i++) | ||
printf("%d ", arr[i]); | ||
printf("\n"); | ||
return 0; | ||
} | ||
``` | ||
|
||
2. Python | ||
``` | ||
def min(x, y): | ||
return x if x < y else y | ||
def merge_sort(arr): | ||
n = len(arr) | ||
a = arr[:] | ||
b = [0] * n | ||
seg = 1 | ||
while seg < n: | ||
for start in range(0, n, seg + seg): | ||
low = start | ||
mid = min(start + seg, n) | ||
high = min(start + seg + seg, n) | ||
k = low | ||
start1 = low | ||
end1 = mid | ||
start2 = mid | ||
end2 = high | ||
while start1 < end1 and start2 < end2: | ||
if a[start1] < a[start2]: | ||
b[k] = a[start1] | ||
start1 += 1 | ||
else: | ||
b[k] = a[start2] | ||
start2 += 1 | ||
k += 1 | ||
while start1 < end1: | ||
b[k] = a[start1] | ||
start1 += 1 | ||
k += 1 | ||
while start2 < end2: | ||
b[k] = a[start2] | ||
start2 += 1 | ||
k += 1 | ||
a, b = b, a | ||
seg += seg | ||
if a != arr: | ||
for i in range(n): | ||
arr[i] = a[i] | ||
arr = [38, 27, 43, 3, 9, 82, 10] | ||
merge_sort(arr) | ||
print(arr) | ||
``` | ||
3. #### 分析 | ||
先将数组分为1个为一组,分了7组, 再1,2;3,4;5,6;7;两两比较,给比较的两组定义一个指针,指针所指的值相互比较, 也就是在这个块`while start1 < end1 and start2 < end2`进行,小的值排左边,直到有一组的指针指向了末尾;如果剩的是第一组的就调用`while start1 < end1`这个块,否则调用`while start2 < end2`这个块。以此类推,分成4组, 分成2组......最终得到有序的数列。 | ||
|
||
## 递归 | ||
1. C | ||
``` | ||
#include <stdio.h> | ||
#include <stdlib.h> // 加入此行以便使用 malloc 和 free | ||
void merge_sort_recursive(int arr[], int reg[], int start, int end) { | ||
if (start >= end) | ||
return; | ||
int len = end - start, mid = (len >> 1) + start; | ||
int start1 = start, end1 = mid; | ||
int start2 = mid + 1, end2 = end; | ||
merge_sort_recursive(arr, reg, start1, end1); | ||
merge_sort_recursive(arr, reg, start2, end2); | ||
int k = start; | ||
while (start1 <= end1 && start2 <= end2) | ||
reg[k++] = arr[start1] < arr[start2] ? arr[start1++] : arr[start2++]; | ||
while (start1 <= end1) | ||
reg[k++] = arr[start1++]; | ||
while (start2 <= end2) | ||
reg[k++] = arr[start2++]; | ||
for (k = start; k <= end; k++) | ||
arr[k] = reg[k]; | ||
} | ||
void merge_sort(int arr[], const int len) { | ||
int reg[len]; | ||
merge_sort_recursive(arr, reg, 0, len - 1); | ||
} | ||
int main() { | ||
int arr[] = { 22, 34, 3, 32, 82, 55, 89 }; | ||
int len = sizeof(arr) / sizeof(*arr); | ||
merge_sort(arr, len); | ||
for (int i = 0; i < len; i++) | ||
printf("%d ", arr[i]); | ||
printf("\n"); // 增加换行以美化输出 | ||
return 0; | ||
} | ||
``` | ||
|
||
2. Python | ||
``` | ||
def merge_sort_recursive(arr, reg, start, end): | ||
if start >= end: | ||
return | ||
mid = (start + end) // 2 | ||
merge_sort_recursive(arr, reg, start, mid) | ||
merge_sort_recursive(arr, reg, mid + 1, end) | ||
start1, end1 = start, mid | ||
start2, end2 = mid + 1, end | ||
k = start | ||
while start1 <= end1 and start2 <= end2: | ||
if arr[start1] < arr[start2]: | ||
reg[k] = arr[start1] | ||
start1 += 1 | ||
else: | ||
reg[k] = arr[start2] | ||
start2 += 1 | ||
k += 1 | ||
while start1 <= end1: | ||
reg[k] = arr[start1] | ||
start1 += 1 | ||
k += 1 | ||
while start2 <= end2: | ||
reg[k] = arr[start2] | ||
start2 += 1 | ||
k += 1 | ||
for k in range(start, end + 1): | ||
arr[k] = reg[k] | ||
def merge_sort(arr): | ||
reg = [0] * len(arr) | ||
merge_sort_recursive(arr, reg, 0, len(arr) - 1) | ||
# 示例使用 | ||
arr = [22, 34, 3, 32, 82, 55, 89] | ||
merge_sort(arr) | ||
print(arr) | ||
``` | ||
|
||
3. ### 分析 | ||
逻辑和迭代法差不多。 |