归并排序基本思想:将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段有序。开辟一个数组用来存放,我们要排的数据。将数组分为两区间,用递归进行对这两个区间数组进行排序,然后去合并它们(合并和链表的合并一样)直到它们有序为止。
void Merger(int array[], int left, int mid, int right, int *exter)
{
int left_index = left;
int right_index = mid;
int exter_index = 0;
//进行两个数组的合成
while (left_index<mid&&right_index<right)
{
if (array[left_index] <= array[right_index]){
exter[exter_index] = array[left_index];
left_index++;
}
else{
exter[exter_index] = array[right_index];
right_index++;
}
exter_index++;
}
//走到这里说明一个数组已经排完了
while (left_index < mid){
exter[exter_index++] = array[left_index++];
}
while (right_index < right){
exter[exter_index++] = array[right_index++];
}
//将新开辟的数组里面的值传到原来数组中去
int size = right - left;
for (int i = 0; i < size; i++){
//注意这里原来数组里面要从left开始,因为传值的时候原来数组有可能已经有值了
array[left + i] = exter[i];
}
}
void _MergerSort(int array[], int left, int right, int *exter)
{
//数组要排序的空间里面有一个或没有值时说明数组有序
if (left + 1 == right){
return;
}
if (left > right){
return;
}
int mid = (right - left) / 2 + left;
//进行递归将数组分成小块进行排序
_MergerSort(array, left, mid, exter);
_MergerSort(array, mid, right, exter);
//将两个数组进行合并
Merger(array, left, mid, right, exter);
}
void MergerSort(int array[], int size)
{
//开辟空间
int *exter = (int *)malloc(sizeof(int)*size);
_MergerSort(array, 0, size, exter);
free(exter);
}
归并排序的特性总结:时间复杂度O(n*logn),空间复杂度O(n),是一个稳定的排序。归并的缺点在于需要O(n)的空间复杂度,归并排序的思考更多的是解决在磁盘中的外排序问题(4g内存,100g硬盘,然后每次从硬盘上面取2g下来进行排序)。