1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
| #include <stdio.h>
#include <stdlib.h>
#define ARRSIZE(arr) (sizeof(arr) / sizeof(arr[0]))
void Sort(int elements[], int tmp[], int leftStart, int rightStart, int rightEnd)
{
int leftEnd = rightStart - 1;
int length = rightEnd - leftStart + 1; //元素长度
int i = leftStart;
//循环条件为左右部分的下标(leftStart rightStart)不越界
while (leftStart <= leftEnd && rightStart <= rightEnd)
{
tmp[i++] = elements[leftStart] > elements[rightStart] ? elements[rightStart++] : elements[leftStart++];
//上面这行代码等效于下面的条件判断
// if (elements[leftStart] > elements[rightStart])
// {
// tmp[i++] = elements[rightStart++];
// }
// else
// {
// tmp[i++] = elements[leftStart++];
// }
}
//上面的while循环,左右两部分有一边下标越界了,那么剩下的另一部分可能还有元素
//所以需要放进tmp中
while (leftStart <= leftEnd)
{
tmp[i++] = elements[leftStart++];
}
while (rightStart <= rightEnd)
{
tmp[i++] = elements[rightStart++];
}
while (rightEnd >= 0)
{
//把tmp中的元素放入elements
elements[rightEnd] = tmp[rightEnd];
rightEnd--;
}
}
void Merge(int elements[], int tmp[], int leftStart, int rightEnd)
{
//表示元素大于1
if (leftStart < rightEnd)
{
int center = (rightEnd + leftStart) / 2; //切割成两份
Merge(elements, tmp, leftStart, center); //递归调用左边部分
Merge(elements, tmp, center + 1, rightEnd); //递归调用右边部分
Sort(elements, tmp, leftStart, center + 1, rightEnd);
}
}
// 此方法用于统一函数接口
void MergeSort(int elements[], int length)
{
int *tmp = (int *)malloc(sizeof(int) * length);
Merge(elements, tmp, 0, length - 1);
free(tmp);
}
int main(int argc, char const *argv[])
{
int elems[] = {3, 4, 2, 1, 5, 9, 2, 1, 0, 22, 33, 5, 112, 11, 22, 55, 22, 61, 97};
int len = ARRSIZE(elems);
MergeSort(elems, len);
for (int i = 0; i < len; i++)
printf("%4d", elems[i]);
printf("\n");
return 0;
}
|