归并排序
归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。归并排序是一种稳定的排序方法。
该算法采用经典的分治(divide-and-conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。
基本思想
先递归分组再合并相邻的两个组
1.将一个待排序序列进行分组,分为左子数组和右子数组,对左右子数组进行排序形成有序的子数组,在进行合并成一个完整的有序序列。
2.对左右子数组进行排序使用递归的方式进行,就是对左右子数组继续进行分组,直到每个组中只有一个元素,说明分组完成,组中的元素已经达到有序,然后在合并相邻的两个组。
3.合并方式为:首先创建一个和原数组相同的数组用来存放合并后的数组,然后比较左右子数组的第一个元素,谁小就把谁放在新数组的0索引处。(如果左子数组的第一个数比右子数组的第一个数小就把左子数组第一个数放在新数组的0索引处,在把左子数组+1继续和右子数组的第一个数进行比较,谁小就把谁放在新数组的1索引处,如果右子数组的第一个数小,就右子数组+1继续和左子数组+1进行比较,谁小就把谁放在新数组的2索引处,依次进行比较,直到合并成一个组,就把新数组里的元素都赋值给原数组)
分解合并的过程图解
归并排序代码(C语言)
#include <stdio.h>
#include <stdlib.h>
//归并排序
//将两个有序子数组合并操作
void Sort(int a[],int temp[],int left,int mid,int right)
{
int i,j,t;
i = left; //左序列指针
j = mid+1; //右序列指针
t = 0; //临时数组指针
while (i <= mid && j <= right)
{
if (a[i] < a[j])
{
temp[t++] = a[i++];
}
else
{
temp[t++] = a[j++];
}
}
while (i<=mid) //将左边剩余元素填充进temp中
{
temp[t++] = a[i++];
}
while (j<=right) // 将右序列剩余元浸塑填充进temp中
{
temp[t++] = a[j++];
}
t=0;
//将temp中的元素全部拷贝到原数组中
while (left <= right)
{
a[left++] = temp[t++];
}
}
//使用递归分组进行
void Merge_Sort(int a[],int temp[],int left,int right)
{
if (left<right)
{
int mid = (left+right)/2;
Merge_Sort(a,temp,left,mid); // 左边归并排序,使得左子序列有序
Merge_Sort(a,temp,mid+1,right); //右边归并排序,使得右子序列有序
Sort(a,temp,left,mid,right); //将两个有序子数组合并操作
}
}
void main()
{
int a[]={16,36,69,56,65,45,52,36,96,2};
int n=sizeof(a)/sizeof(int); //计算数组元素
int i,b[n];
Merge_Sort(a,b,0,n);
for ( i = 0; i < n; i++)
{
printf("%d ",a[i]);
}
system("pause"); //防止控制台闪退
}
参考文献
图解排序算法(四)之归并排序