这是我参与8月更文挑战的第15天,活动详情查看:8月更文挑战
概念
归并排序(Merge Sort)是建立在归并操作上的一种有效,稳定的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
“归并”的含义是将两个或两个以上的有序表组合成一个新的有序表。假设待排序表含有n个记录,则可将其视为n个有序的子表,每个子表的长度为一,然后两两归并,得到【n/2】个长度为2或1的有序表;继续两两归并。。。如此重复,直到合并成一个长度为n的有序表为止,这种排序方法称为2路归并排序。
归并排序是使用到了分治方法(Divide and Conquer)。
-
Divide:将原问题分解为若干子问题,其中这些子问题的规模小于原问题的规模。
-
Conquer:递归地求解子问题,当子问题规模足够小时直接求解。
-
Merge:将子问题的解合并得到原问题的解。
归并操作的工作原理如下:
第一步:申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
第二步:设定两个指针,最初位置分别为两个已经排序序列的起始位置
第三步:比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
重复步骤3直到某一指针超出序列尾
将另一序列剩下的所有元素直接复制到合并序列尾
算法实现
/*****************归并排序*****************/
int guibing = 10;//和总体表的大小一致
ElemType* B = (ElemType*)malloc((guibing + 1) * sizeof(ElemType));//辅助数组B
void Merge(ElemType A[],int low,int mid,int high)
{
int i, j,k;
//表A[low...mid]和A[mid+1...high]各自有序,将他们合并成一个有序表
for (int k = low; k <= mid; k++)
B[k] = A[k];
for (int i = low, j = mid + 1, k = i; i <= mid && j <= high; k++)
{
if (B[i] <= B[j])
A[k] = B[i++];//将较小值复制到A中
else
A[k] = B[j++];
}
while (i <= mid)
A[k++] = B[i++];//若第一个表未检测完,复制
while (j <= high)
A[k++] = B[j++];
}
void Merge_Sort(ElemType A[],int low,int high)
{
if (low < high)
{
int mid = (low+high)/2; //划分成两个子序列
Merge_Sort(A,low,mid);
Merge_Sort(A,mid+1,high);
Merge(A,low,mid,high); //归并
}
}