归并排序

来源:互联网 发布:淘宝客服搞笑语录 编辑:程序博客网 时间:2024/06/10 06:34

归并排序是创建在归并操作上的一种有效的排序算法,效率为O(nlogn),1945年由冯·诺伊曼首次提出。

  归并排序的实现分为递归实现非递归(迭代)实现。递归实现的归并排序是算法设计中分治策略的典型应用,我们将一个大问题分割成小问题分别解决,然后用所有小问题的答案来解决整个大问题。非递归(迭代)实现的归并排序首先进行是两两归并,然后四四归并,然后是八八归并,一直下去直到归并了整个数组。

  归并排序算法主要依赖归并(Merge)操作。归并操作指的是将两个已经排序的序列合并成一个序列的操作,归并操作步骤如下:

  1. 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
  2. 设定两个指针,最初位置分别为两个已经排序序列的起始位置
  3. 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
  4. 重复步骤3直到某一指针到达序列尾
  5. 将另一序列剩下的所有元素直接复制到合并序列尾

  归并排序的代码如下:

#include <stdio.h>


// 交换函数
void swap (int a[], int i, int j)
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}


// 打印数组
void printA (int *a, int len)
{
int i;
for (i = 0; i < len; i++)
{
printf ("%4d", a[i]);
}

printf ("\n");
}


// a 是数组  tmp  是缓冲区
void merge(int *a, int left, int mid, int right, int *tmp)
{
int i = left;
int j = mid + 1;
int k = 0;

while (i <= mid && j <= right)
{
if (a[i] > a[j])
tmp[k++] = a[j++];
else
tmp[k++] = a[i++];
}

while (i <= mid)
tmp[k++] = a[i++];

while (j <= right)
tmp[k++] = a[j++];

k = 0;
for (i = left; i <= right; i++)
{
a[i] = tmp[k++];
}
}


void mergeSort(int *a, int left, int right, int *tmp)
{
if (left >= right)
return;

int mid = (left + right)/2;
mergeSort (a, left, mid, tmp);    // 对左边部分进行归并排序
mergeSort (a, mid+1, right, tmp); // 对右边部分进行归并排序
merge (a, left, mid, right, tmp); // 将将部分数据进行归并
}


int main()
{
int a[10] = {9,6,8,0,3,1,2,4,7,5};
int len = sizeof(a) / sizeof(a[0]);
int tmp[10];
mergeSort (a, 0, len-1, tmp);
printA (a, len);

return 0;
}