Chinaunix首页 | 论坛 | 博客
  • 博客访问: 149828
  • 博文数量: 14
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 145
  • 用 户 组: 普通用户
  • 注册时间: 2014-02-12 15:27
个人简介

文章分类

全部博文(14)

文章存档

2014年(14)

分类: C/C++

2014-02-20 17:49:54

一、归并排序(merge sort)
       原理:归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。原理是将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。具体操作步骤如下:
               第一步:申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
               第二步:设定两个位置,最初位置分别为两个已经排序序列的起始位置
               第三步:比较两个位置的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
               重复步骤3直到某一指针超出序列尾
          将另一序列剩下的所有元素直接复制到合并序列尾。
       以{49, 13, 65, 38, 27, 45, 31}序列为例排序过程如下图:
       
       代码实现:

点击(此处)折叠或打开

  1. /************************************************************************/
  2. /* 合并两个有序序列
  3.    将a[start...mid] 与 a[mid+1...end] 合并
  4. */
  5. /************************************************************************/
  6. void merge(int *a, int start, int mid, int end)
  7. {
  8.     int i = start, j = mid + 1, k = 0;
  9.     int *array = NULL;
  10.     
  11.     if(start > mid || mid > end) return;

  12.     /* 为array分配空间,保存a[start...end] */
  13.     array = (int *)calloc(end - start + 1, sizeof(int));
  14.     
  15.     while((i <= mid) && (j <= end))
  16.     {
  17.         if(a[i] < a[j])
  18.             array[k++] = a[i++];
  19.         else
  20.             array[k++] = a[j++];
  21.     }

  22.     while(i <= mid)
  23.         array[k++] = a[i++];

  24.     while(j <= end)
  25.         array[k++] = a[j++];

  26.     for(i = start, j = 0; i <= end; i++, j++)
  27.         a[i] = array[j];

  28.     free(array);
  29. }
  30. /************************************************************************/
  31. /* 归并排序 */
  32. /************************************************************************/
  33. void MergeSort(int *a, int start, int end)
  34. {
  35.     if(start < end)
  36.     {
  37.         int mid = (end + start) / 2;

  38.         MergeSort(a, start, mid);
  39.         MergeSort(a, mid + 1, end);
  40.         merge(a, start, mid, end);
  41.     }
  42. }
        性能分析:归并排序消耗的时间是分解时间+排序时间+合并时间的总和。在最坏、最佳、平均情况下归并排序时间复杂度均为o(nlogn)。并且需要有和原序列相同大小的辅助空间。所以归并排序应用于总体无序,但子项相对有序,并且数据量不是很大的情况下,而且效率仅次于快速排序。

阅读(2389) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~