归并排序
归并排序的思想:将数组一分为二,分别对左右两个数组进行排序,然后对左右两个有序数组归并成一个有序数组
时间复杂度:O(nlogn)
自顶向下的代码
template<typename T>
void __merge(T arr[], int l, int mid, int r)
{
int len_left = mid - l + 1;
int len_right = r - mid;
int auxL[len_left];
int auxR[len_right];
for(int i = 0; i < len_left; i++)
auxL[i] = arr[l+i];
for(int i = 0; i < len_right; i++)
auxR[i] = arr[mid + 1 +i];
int i = 0, j = 0;
while(i < len_left && j < len_right)
{
if( auxL[i] <= auxR[j] )
arr[l+i+j] = auxL[i++];
else
arr[l+i+j] = auxR[j++];
}
while(i < len_left)
arr[l+i+j] = auxL[i++];
while(j < len_right)
arr[l+i+j] = auxR[j++];
}
template<typename T>
void __mergeSort_(T arr[], int l, int r){ //arr[l,r]进行排序
if(l >= r)
return;
//小数组的时候可以考虑使用插入排序进行优化
// if(r - l <= 15)
//insertSort(arr,l,r)
int mid = l + (r - l) / 2;
__mergeSort_(arr, l, mid);
__mergeSort_(arr, mid+1,r);
if( arr[mid] > arr[mid+1] ) //只有当左边数组的最大值大于右边数组的最小值时才进行merge
__merge(arr, l ,mid , r);
return;
}
template<typename T>
void mergeSort( T arr[], int n){
__mergeSort_(arr, 0, n-1);
return;
}
自底向上的归并排序
优点:没有用到索引,所以可以用到链表的排序中
代码实现使用了自顶向下的merge方法
template<typename T>
void mergeSortBU( T arr[], int n){
for(int sz = 1; sz < n; sz *= 2)
for(int i = 0; i + sz < n; i+= 2*sz)//注意i +sz必须小于n才能分成两份
if(arr[i+sz-1] > arr[i+sz]) //只有当左边数组的最大值大于右边数组的最小值时才进行merge
__merge(arr, i, i + sz -1, min(i+2*sz -1, n-1));//注意i+2*size-1可能越界,因此取min
return;
}