归并排序比较简单易懂,是将两个或者两个以上的有序表合并为一个新的有序表,即把待排序的数组分为若干个子序列,每个子序列是有序的,
然后把有序子序列合并为有序序列
工作原理为:申请空间,使其大小为两个已排序序列大小之和,用来存放合并后的序列
设定两个指针,分别指向两个以排序数组的起始位置
比较两个指针所指向的元素,选择较小的元素放入合并空间,并移动指针到下一位置
重复直到某一指针达到数组尾
将另一数组剩下的所有元素直接复制到合并数组尾
C语言描述
void MergeSort(int a[], int first, int last) {
void Merge(int a[], int p, int q, int r);
int mid = 0;
if(first < last) {
//将待排序数组分为两部分,且分别有序
mid = (first + last) / 2;
//一直递归调用,最终相邻的两个元素有序,
MergeSort(a, first, mid);
MergeSort(a,mid+1, last);
//将已排序的两个子区间归并
Merge(a,first,mid,last);
}
}
void Merge(int a[], int p, int q, int r) {
int i,k;
int begin1, begin2, end1, end2;
//申请空间,存放排序数组
int *temp = (int *)malloc((r-p+1) * sizeof(int));
if(! temp) //申请空间失败
printf("Insufficient memory available!");
//第一个数组的头
begin1 = p;
//第一个数组的尾
end1 = q;
//第二个数组的头
begin2 = q + 1;
//第二个数组的尾
end2 = r;
//要存放数组的位置
k = 0;
while((begin1 <= end1) && (begin2 <= end2)) {
//比较两个有序数组,取较小值放入排序数组
if(a[begin1] < a[begin2]) {
temp[k] = a[begin1];
begin1++;
} else {
temp[k] = a[begin2];
begin2++;
}
//排序数组后移
k++;
}
//若还有剩余元素,全部复制到排序数组
while(begin1 <= end1) {
temp[k++] = a[begin1++];
}
while(begin2 <= end2) {
temp[k++] = a[begin2++];
}
//复制到待排序数组中
for(i=0; i <= (r-p); i++) {
a[p+i] = temp[i];
}
free(temp);
然后把有序子序列合并为有序序列
工作原理为:申请空间,使其大小为两个已排序序列大小之和,用来存放合并后的序列
设定两个指针,分别指向两个以排序数组的起始位置
比较两个指针所指向的元素,选择较小的元素放入合并空间,并移动指针到下一位置
重复直到某一指针达到数组尾
将另一数组剩下的所有元素直接复制到合并数组尾
C语言描述
void MergeSort(int a[], int first, int last) {
void Merge(int a[], int p, int q, int r);
int mid = 0;
if(first < last) {
//将待排序数组分为两部分,且分别有序
mid = (first + last) / 2;
//一直递归调用,最终相邻的两个元素有序,
MergeSort(a, first, mid);
MergeSort(a,mid+1, last);
//将已排序的两个子区间归并
Merge(a,first,mid,last);
}
}
void Merge(int a[], int p, int q, int r) {
int i,k;
int begin1, begin2, end1, end2;
//申请空间,存放排序数组
int *temp = (int *)malloc((r-p+1) * sizeof(int));
if(! temp) //申请空间失败
printf("Insufficient memory available!");
//第一个数组的头
begin1 = p;
//第一个数组的尾
end1 = q;
//第二个数组的头
begin2 = q + 1;
//第二个数组的尾
end2 = r;
//要存放数组的位置
k = 0;
while((begin1 <= end1) && (begin2 <= end2)) {
//比较两个有序数组,取较小值放入排序数组
if(a[begin1] < a[begin2]) {
temp[k] = a[begin1];
begin1++;
} else {
temp[k] = a[begin2];
begin2++;
}
//排序数组后移
k++;
}
//若还有剩余元素,全部复制到排序数组
while(begin1 <= end1) {
temp[k++] = a[begin1++];
}
while(begin2 <= end2) {
temp[k++] = a[begin2++];
}
//复制到待排序数组中
for(i=0; i <= (r-p); i++) {
a[p+i] = temp[i];
}
free(temp);
}
较难理解的是原本是一个无序序列,怎么构造两个有序序列进行归并呢?
可以这样考虑,假设有8个元素,则分别将a[0]与a[1],a[2]与a[3],a[4]与a[5],a[6]与a[7]进行归并排序,即相邻的两个元素有序,这时再将a[0],a[1],a[2],a[3]以及a[4],a[5],a[6],a[7]进行归并排序,如此重复归并下去......这样最终就会构造成一个有序序列
也就是说,是由下到上进行的归并排序