归并排序C语言版

归并排序的基本思想:

将两个及其以上的有序表合并为一张有序表,把待排序序列通过分治法分为若干个有序子序列,然后每两个子序列合并为一个子序列,经过多次合并后整合为一张有序表。

归并排序是稳定排序,它也是一种十分高效的排序,能利用完全二叉树特性的排序一般性能都不会太差。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);
 }
 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值