递归实现归并排序思想
- 使用递归的方法来分元素
- 使用临时数组来保存排好序的元素
- 把临时数组中的元素拷贝给原数组
void mergeAdd(int arr[], int left, int mid, int right, int *temp){实现“治”
int i = left;
int j = mid + 1;
int k = left;//临时下标
while (i <= mid&&j <= right){
if (arr[i] < arr[j]){
temp[k++] = arr[i++];
}
else{
temp[k++] = arr[j++];
}
}
while (i <= mid){
temp[k++] = arr[i++];
}
while (j <= right){
temp[k++] = arr[j++];
}
//把temp中的内容拷给arr数组中
//进行归并的时候,处理的区间是arr[left,right),对应的会把
//这部分区间的数组填到tmp[left,right)区间上
memcpy(arr + left, temp + left, sizeof(int)*(right - left+1));
}
void mergeSort(int arr[],int left,int right,int *temp){//实现“分”
int mid = 0;
if (left < right){
mid = left + (right - left) / 2;
mergeSort(arr, left, mid, temp);
mergeSort(arr, mid + 1, right, temp);
mergeAdd(arr, left, mid, right, temp);
}
}
测试代码
int main(){
int arr[] = { 8,4,5,7,1,3,6,2};
int len = sizeof(arr)/sizeof(arr[0]);
int *temp = (int*)malloc(sizeof(int)*len);
mergeSort(arr, 0, len - 1, temp);
free(temp);
for (int i = 0; i < len; i++){
printf("%d ", arr[i]);
}
system("pause");
return 0;
}
递归归并排序性质
时间复杂度:O(NlogN)
空间复杂度:O(N)
稳定性:稳定排序
非递归实现归并排序
void mergeAdd1(int arr[], int left, int mid, int right, int *tmp){
int i = left;
int j = mid + 1;
int k = left;//临时下标
while (i <= mid&&j <= right){
if (arr[i] < arr[j]){
temp[k++] = arr[i++];
}
else{
temp[k++] = arr[j++];
}
}
while (i <= mid){
temp[k++] = arr[i++];
}
while (j <= right){
temp[k++] = arr[j++];
}
//把temp中的内容拷给arr数组中
//进行归并的时候,处理的区间是arr[left,right),对应的会把
//这部分区间的数组填到tmp[left,right)区间上
memcpy(arr + left, temp + left, sizeof(int)*(right - left + 1));
}
void mergeSort2(int arr[], int len,int* tmp){
if (len <= 1){
return;
}
//定义一个步长gap,初始值为1,相当于每次只合并两个长度为1的元素
int gap = 1;
for (; gap <= len; gap *= 2){
int i = 0;
for (; i <= len; i += 2 * gap){
int beg = i;
int mid = (gap - 1) + i;
if (mid >= len){
mid = len;
}
int end = mid + gap;
if (end >= len){
end = len;
}
mergeAdd1(arr, beg, mid, end, tmp);
}
}
}
测试代码同上。