归并排序
归并排序用到了递归的思想,相比较冒泡排序、选择排序和插入排序(时间复杂度为 O(NN),时间复杂度为O(NlogN),当样本量N很大的时候,要比这三种排序方法要好很多。
归并排序的思想是这样的:先将需要排序的数组分成左半部分和右半部分(当N很大时候不需要考虑N到底是奇数还是偶数),对左半部分和右半部分分别进行排序,两部分排好序后再进行整体排序。在对左半部分排序时,同样对左半部分分成两部分,分别进行排序。同理,在对右半部分进行排序也是同样的道理。这样不断的递归下去就可以对整个数组进行排序。
直接上代码:
# include <stdio.h>
void merge(int tempArr[], int arr[], int left, int midd, int right)
{
int i,j,k,p;
i = left; j = midd+1;
for(k = left; k <= right; k++)
{
if(i > midd) //左边数都放完,右边还没,即当现在右边的数都大于左边时
{
tempArr[k] = arr[j]; //直接把右边的数放到数组后面
j ++; //j为右半部分下标
}
else if(j > right) //右边数都放完,左边还没,即当现在左边的数都大于右边时
{
tempArr[k] = arr[i]; //直接把左边的数放到数组后面
i ++; //i为左半部分下标
}
else if(arr[i] <= arr[j])//左右两边都还没放完,左边部分和右半部分进行比较
{
tempArr[k] = arr[i]; //谁小放谁
i ++;
}
else //右两边都还没放完,左边部分和右半部分进行比较
{
tempArr[k] = arr[j]; //谁小放谁
j ++;
}
}
for(p = left; p <= right; p ++)
{
arr[p] = tempArr[p]; //执行完排序后传递回去
}
}
void mergeSort(int arr[],int tempArr[], int left, int right)
{
if(left >= right) //给定结束条件
return ;
int middle = left +((right - left) >>1 ); //(right + left) / 2;
mergeSort(arr,tempArr,left,middle); //递归排序left至middle
mergeSort(arr,tempArr,middle+1,right); //递归排序middle+1至right
merge(tempArr,arr,left,middle,right); //排序整个数组
}
int main(void)
{
int a[] = {500, 22, 53, -158, 4, 86, 32, 33, 26, -70, 135, -34, 32, 543, 2500};
int n; //存放数组a中元素的个数
int i;
n = sizeof(a) / sizeof(a[0]); /*a[0]是int型, 占4字节*/
int b[n]; //临时存储用
mergeSort(a,b,0,n-1);
for(i = 0; i< n-1; i ++)
{
printf("%d\t",b[i]);
}
printf("\r\n");
return 0;
}