1. Merge sort (v1)
1.1 C++实现
// 将arr[l...mid]和arr[mid+1...r]两部分进行归并
template<typename T>
void __merge(T arr[], int l, int mid, int r){
//* VS不支持动态长度数组, 即不能使用 T aux[r-l+1]的方式申请aux的空间
//* 使用new申请空间, 不要忘了在__merge函数的最后, delete掉申请的空间:)
T aux[r-l+1];
//T *aux = new T[r-l+1];
for( int i = l ; i <= r; i ++ )
aux[i-l] = arr[i];
// 初始化,i指向左半部分的起始索引位置l;j指向右半部分起始索引位置mid+1
int i = l, j = mid+1;
for( int k = l ; k <= r; k ++ ){
if( i > mid ){ // 如果左半部分元素已经全部处理完毕
arr[k] = aux[j-l]; j ++;
}
else if( j > r ){ // 如果右半部分元素已经全部处理完毕
arr[k] = aux[i-l]; i ++;
}
else if( aux[i-l] < aux[j-l] ) { // 左半部分所指元素 < 右半部分所指元素
arr[k] = aux[i-l]; i ++;
}
else{ // 左半部分所指元素 >= 右半部分所指元素
arr[k] = aux[j-l]; j ++;
}
}
//delete[] aux;
}
// 递归使用归并排序,对arr[l...r]的范围进行排序
template<typename T>
void __mergeSort(T arr[], int l, int r){
if( l >= r )
return;
int mid = (l+r)/2;
__mergeSort(arr, l, mid);
__mergeSort(arr, mid+1, r);
__merge(arr, l, mid, r);
}
template<typename T>
void mergeSort(T arr[], int n){
__mergeSort( arr , 0 , n-1 );
}
1.2 Python实现
def __merge(arr, l, mid, r):
aux = []
for i in range(l, r+1):
aux.append(arr[i])
i, j = l, mid+1
for k in range(l, r+1):
if i > mid:
arr[k] = aux[j-l]
j += 1
elif j > r:
arr[k] = aux[i-l]
i += 1
elif aux[i-l] < aux[j-l]:
arr[k] = aux[i-l]
i += 1
else:
arr[k] = aux[j-l]
j += 1
def __merge_sort(arr, l, r):
if l >= r:
return
mid = (l + r) // 2
__merge_sort(arr, l, mid)
__merge_sort(arr, mid+1, r)
__merge(arr, l, mid, r)
def merge_sort_v1(arr):
n = len(arr)
__merge_sort(arr, 0, n-1)
2. Merge sort (v2)
v1对一个近乎有序的数组排序性能不佳,v2解决了此问题,在近乎有序的大型数组上排序有显著的速度提升。但是对于常规数组,会有一定的性能损失,因为v2相比v1多了一个if判断语句,但是这个损失是可以接受的。
2.1 C++实现
template<typename T>
void insertionSort(T arr[], int l, int r){
for( int i = l+1 ; i <= r ; i ++ ) {
T e = arr[i];
int j;
for (j = i; j > l && arr[j-1] > e; j--)
arr[j] = arr[j-1];
arr[j] = e;
}
return;
}
template<typename T>
void __merge(T arr[], int l, int mid, int r){
T aux[r-l+1];
//T *aux = new T[r-l+1];
for( int i = l ; i <= r; i ++ )
aux[i-l] = arr[i];
int i = l, j = mid+1;
for( int k = l ; k <= r; k ++ ){
if( i > mid ){
arr[k] = aux[j-l]; j ++;
}
else if( j > r ){
arr[k] = aux[i-l]; i ++;
}
else if( aux[i-l] < aux[j-l] ) {
arr[k] = aux[i-l]; i ++;
}
else{
arr[k] = aux[j-l]; j ++;
}
}
//delete[] aux;
}
template<typename T>
void __mergeSort2(T arr[], int l, int r){
if l >= r:
return
int mid = (l+r)/2;
__mergeSort2(arr, l, mid);
__mergeSort2(arr, mid+1, r);
// 优化: 对于arr[mid] <= arr[mid+1]的情况,不进行merge
// 对于近乎有序的数组非常有效,但是对于一般情况,有一定的性能损失
if( arr[mid] > arr[mid+1] )
__merge(arr, l, mid, r);
}
template<typename T>
void mergeSort(T arr[], int n){
__mergeSort( arr , 0 , n-1 );
}
2.2 Python实现
def __merge(arr, l, mid, r):
aux = []
for i in range(l, r+1):
aux.append(arr[i])
i, j = l, mid+1
for k in range(l, r+1):
if i > mid:
arr[k] = aux[j-l]
j += 1
elif j > r:
arr[k] = aux[i-l]
i += 1
elif aux[i-l] < aux[j-l]:
arr[k] = aux[i-l]
i += 1
else:
arr[k] = aux[j-l]
j += 1
def __merge_sort(arr, l, r):
if l >= r:
return
mid = (l + r) // 2
__merge_sort(arr, l, mid)
__merge_sort(arr, mid+1, r)
if arr[mid] > arr[mid+1]:
__merge(arr, l, mid, r)
def merge_sort_v2(arr):
n = len(arr)
__merge_sort(arr, 0, n-1)