算法思想
分治法,分而治之。将一个大的问题分解成若干个小问题去解决,小问题解决了,大问题自然也就解决了。
代码实现
#include <iostream>
using namespace std;
void merge(int *arr, int start, int middle, int end)
{
int i, j, k;//i指向左边的数组,j指向右边的数组,k指向原来的数组
int leftSize = middle+1-start;
int rightSize = end-middle;
//开辟新的内存存放左右两个数组
int *left = (int *)malloc(leftSize*sizeof(int));
int *right = (int *)malloc(rightSize*sizeof(int));
for(i=0; i<leftSize; i++) //左边的数组赋值
left[i] = arr[start+i];
for(j=0; j<rightSize; j++) //右边的数组赋值
right[j] = arr[middle+1+j];
i = j = 0;
k = start;
while(i<leftSize && j<rightSize) //两个数组的头指针元素两两比较
{
if(left[i] <= right[j])
arr[k++] = left[i++];
else
arr[k++] = right[j++];
}
//有一边数组遍历完了,但另一个数组还有元素,则将剩下的全部按顺序放到arr中
for(; i<leftSize; i++)
arr[k++] = left[i];
for(; j<rightSize; j++)
arr[k++] = right[j];
free(left);
free(right);
}
void mergeSort(int *arr, int left, int right)
{
int middle;//分割的依据
if(left < right)
{
middle = (int)((left+right)/2);
mergeSort(arr, left, middle); //递归分割左数组
mergeSort(arr, middle+1, right); //递归分割右数组
merge(arr, left, middle, right); //合并
}
}
int main()
{
int n=10;
int arr[10] = {9,4,3,8,2,0,10,3,7,5};
cout<<"排序前:";
for(int i=0; i<n; ++i)
cout<<arr[i]<<" ";
cout<<endl;
//归并排序
mergeSort(arr,0,n-1);
cout<<"排序后:";
for(int i=0; i<n; ++i)
cout<<arr[i]<<" ";
cout<<endl;
system("pause");
return 0;
}
VS2010运行结果:
- 时间复杂度
分:O(logn)
治:O(n)
所以总的时间复杂度为:O(nlogn) - 空间复杂度
开辟了新的临时空间存放数组,所以空间复杂度为:O(n) - 稳定性
在两个元素相等时,先放的还是前面的数据,所以说是稳定的排序。