介绍
从头实现归并排序。
归并排序(MergeSort),是采用分治思想的一种算法,通过把要排序的数组依次递归对半拆分,当子数组达到长度1时,即只有一个元素,认为其为有序的,结束递归。使用递归排序时,无论原数组序列的排序情况如何,都要递归到最底层,所以时间复杂度相对固定。为
O
(
n
l
o
g
(
n
)
)
O(nlog(n))
O(nlog(n)). 归并排序可分为二路归并和多路归并,最常用的是二路归并,下文示例亦是针对二路归并排序的。另外,归并排序是稳定的。
图解
拆分阶段:
合并阶段:
示例代码
def mergeSort(arr): # 拆分
if len(arr) // 2 == 0:
return arr
return merge(mergeSort(arr[0:len(arr) // 2]), mergeSort(arr[len(arr) // 2:]))
def merge(a_l, a_r): # 合并
a = [0] * (len(a_l) + len(a_r))
p_l, p_r = 0, 0 # 左右数组的左右指针
while p_l < len(a_l) and p_r < len(a_r):
if a_l[p_l] > a_r[p_r]:
a[p_l + p_r] = a_r[p_r]
p_r += 1
else:
a[p_l + p_r] = a_l[p_l]
p_l += 1
while p_l < len(a_l): # 若左数组剩余,依次填入
a[p_l + p_r] = a_l[p_l]
p_l += 1
while p_r < len(a_r): # 若右数组剩余,依次填入
a[p_l + p_r] = a_r[p_r]
p_r += 1
return a
if __name__ == '__main__':
a = [16, 55, 64, 35, 24, 4, 85, 68, 84, 41]
out = mergeSort(a)
print(out)
[out]:
[4, 16, 24, 35, 41, 55, 64, 68, 84, 85]
import java.util.Arrays;
public class MergeSort {
public static void main(String[] args) {
int[] arr = new int[]{97, 76, 84, 35, 60, 53, 59, 62, 93, 53, 37, 19, 9};
arr = mergeSort(arr);
for (int i : arr) {
System.out.println(i);
}
}
public static int[] mergeSort(int[] arr) {
int len = arr.length;
if (len / 2 == 0) {
return arr;
}
int[] arr_l = mergeSort(Arrays.copyOfRange(arr, 0, len / 2));
int[] arr_r = mergeSort(Arrays.copyOfRange(arr, len / 2, len));
return merge(arr_l, arr_r);
}
public static int[] merge(int[] arr_l, int[] arr_r) {
int len_l = arr_l.length;
int len_r = arr_r.length;
int[] arr = new int[len_l + len_r];
int p_l = 0;
int p_r = 0;
while (p_l < len_l && p_r < len_r) {
if (arr_l[p_l] < arr_r[p_r]) {
arr[p_l + p_r] = arr_l[p_l];
p_l++;
} else {
arr[p_l + p_r] = arr_r[p_r];
p_r++;
}
}
while (p_l < len_l) {
arr[p_l + p_r] = arr_l[p_l];
p_l++;
}
while (p_r < len_r) {
arr[p_r + p_l] = arr_r[p_r];
p_r++;
}
return arr;
}
}
[out]:
9
19
35
37
53
53
59
60
62
76
84
93
97
];
p_r++;
}
return arr;
}
}
[out]:
9
19
35
37
53
53
59
60
62
76
84
93
97