归并排序
这里用递归实现了归并排序,左边排序->右边排序->让其整体有序。
让其整体有序的过程中使用了排外序的方法。即构造一个新的数组,比较对i, j所指向的数字进行大小比较,如果arr[i] >arr[j],则将arr[i] 的值复制到新数组中,i + 1,j 不变。这样依次遍历,直到 i 或 j 到达临界点,跳出循环。将剩余部分直接拷贝到新数组中。
根据 master 公式,归并排序的时间复杂度为 O(logN * N),空间复杂度为O(N)。
归并排序的实质
代码实现:
class Sort{
public:
static void merge(int arr[],int L,int mid,int R){
int i = L;
int j = mid + 1;
int k = 0;
int *temp_arr = new int(R - L + 1);
for( ; i <= mid && j <= R; ){
temp_arr[k++] = arr[i] > arr[j] ? arr[i++] : arr[j++];
}
while(i <= mid){
temp_arr[k++] = arr[i++];
}
while(j <= R){
temp_arr[k++] = arr[j++];
}
for(i = L,k = 0; i <= R; i++,k++){
arr[i] = temp_arr[k];
}
delete temp_arr;
}
static void mergeSort(int arr[],int L,int R){
if(L == R)
return;
int mid = L + ((R - L) >> 1);
cout << mid << endl;
mergeSort(arr,L,mid);
mergeSort(arr,mid+ 1,R);
merge(arr,L,mid,R);
}
static void mergeSort(int arr[],int length){
if(arr == NULL || length <= 0)
return;
mergeSort(arr,0,length - 1);
}
};
例题:
1. 小和问题:一个数组中,每一个数左边比当前数小的数累加起来,叫做这个数组的小和。求一个数组的小和。 例子:[1,3,4,2,5] 1左边比1小的数,没有; 3左边比3小的数,1; 4左 边比4小的数,1、3; 2左边比2小的数,1; 5左边比5小的数,1、3、4、 2; 所以小和为1+1+3+1+1+3+4+2=16
static int merge(int arr[],int L,int mid,int R){
int i = L;
int j = mid + 1;
int k = 0;
int res = 0;
int* temp_arr = new int(R - L + 1);
for( ; i <= mid && j <= R; ){
res += arr[i] < arr[j] ? arr[i] * (R - j + 1) : 0;
temp_arr[k++] = arr[i] < arr[j] ? arr[i++] : arr[j++];
}
while(i <= mid){
temp_arr[k++] = arr[i++];
}
while(j <&