排序思路: 分治+递归(创建临时数组)
1.将序列中待排序数字分为若干组,先以(left+right)/2为分界分成两组,再对左半边和右半边分别递归,直到每个数字分为一组(其是就是先对半分,直到分成都是一个,有点像二叉树);
2.将若干个组两两合并,保证合并后的组是有序的(合并样子有点像倒过来的二叉树);
3.重复第二步操作直到只剩下一组,排序完成。
代码的实现:
/*函数声明*/
void merge_sort(int arr[],int tempArr[],int left,int right );
void merge(int arr[],int tempArr[],int left,int mid,int right);
/*排序入口:先从内存分配临时数组*/
void mergeSort(int arr[],int N){
int *tempArr =(int *)malloc(N * sizeof(int));
/*分配成功,开始划分*/
if(tempArr){
merge_sort(arr,tempArr,0,N-1);
/*用完释放内存*/
free(tempArr);
}else{
/*失败,报错*/
printf("failed to allocate memory\n");
}
}
/*分*/
void merge_sort(int arr[],int tempArr[],int left,int right ){
if(left<right){
int mid = (right+left)/2;
/*递归划分左半区*/
merge_sort(arr,tempArr,left,mid);
/*递归划分右半区*/
merge_sort(arr,tempArr,mid+1,right);
/*划分完成,开始治(合并)*/
merge(arr,tempArr,left,mid,right);
}
}
/*治(合并)*/
void merge(int arr[],int tempArr[],int left,int mid,int right){
/*标记左半区第一个*/
int i = left;
/*标记右半区域第一个*/
int j = mid + 1;
int t = left;
/*合并操作(小的先)*/
while(i<=mid && j<=right){
if(arr[i]<=arr[j])
tempArr[t++] = arr[i++];
else
tempArr[t++] = arr[j++];
}
/*左半区剩下的元素*/
while(i<=mid){
tempArr[t++] = arr[i++];
}
/*右半区剩下的元素*/
while(j<=right){
tempArr[t++] = arr[j++];
}
/*临时数组拷贝给原数组*/
while(left<=right){
arr[left] = tempArr[left];
left++;
}
}