归并排序的基本思想:
将两个及其以上的有序表合并为一张有序表,把待排序序列通过分治法分为若干个有序子序列,然后每两个子序列合并为一个子序列,经过多次合并后整合为一张有序表。
归并排序是稳定排序,它也是一种十分高效的排序,能利用完全二叉树特性的排序一般性能都不会太差。java中Arrays.sort()采用了一种名为TimSort的排序算法,就是归并排序的优化版本。从上文的图中可看出,每次合并操作的平均时间复杂度为O(n),而完全二叉树的深度为|log2n|。总的平均时间复杂度为O(nlogn)。而且,归并排序的最好,最坏,平均时间复杂度均为O(nlogn)。
/*
* 将两个无序的归并为一个有序的
*/
void merge(int *arr,int low,int mid,int high)
{
int i = low;
int j = mid+1;
int k = 0;
int *temp = (int *)malloc(sizeof(int)*(high - low + 1));
if(temp == NULL) return;
while(i <= mid && j <= high)
{
if(arr[i] <= arr[j])
{
temp[k++] = arr[i++];
}
else
{
temp[k++] = arr[j++];
}
}
while(i <= mid) temp[k++] = arr[i++];
while(j <= high) temp[k++] = arr[j++];
for(i=low,k=0;i<=high;i++,k++)
{
arr[i] = temp[k];
}
free(temp);
}
/*
*采用非递归的方法归并
*
*/
void merge_sort(int *arr,int length) //length是数组元素的个数
{
int low;
int mid;
int high;
int size = 1;
while(size < length - 1)
{
low = 0;
while(low + size <= length - 1)
{
mid = low + size -1;
high = mid + size;
if(high > length - 1)
{
high = length - 1;
}
merge(arr,low,mid,high);
low = high + 1;
}
size *= 2;
}
}
-----------------------------------------------------------------------------------------
void merge_sort_down(int *arr,int start,int end)
{
if(arr == NULL || start >= end) return;
int mid =(start+end)/2;
merge_sort_down(arr,start,mid); //递归排序arr[start,..,mid]
merge_sort_down(arr,mid+1,end); //递归排序arr[mid,..,end]
merge(arr,start,mid,end);
}
/*
*采用递归的方法归并
*
*/
void merge_sort(int *arr,int length)
{
merge_sort_down(arr,0,length-1);
}