继quick sort后的第二个排序,merge sort,依然是分治的思想,将原数组分成若干个小数组,排序,然后再慢慢合并成大数组。
实现代码:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
void merge(int a[], int b[], int lst, int rst, int re)
{
int i, le, nums, tmp;
le = rst - 1;
tmp = lst;
nums = re - lst + 1;
while(lst <= le && rst <= re)//比较复制到临时表中
if(a[lst] >= a[rst])
b[tmp++] = a[lst++];
else
b[tmp++] = a[rst++];
while(lst <= le)//将未完成的复制完成
b[tmp++] = a[lst++];
while(rst <= re)
b[tmp++] = a[rst++];
for(int i = 0; i < nums; i++, re--)//将临时数组中的内容拷贝回去 注意b中的顺序是和最后数组的顺序相反的
a[re] = b[re];
}
void Msort(int a[], int b[], int left, int right)
{
int center;
if(left < right)
{
center = (left + right) / 2;
Msort(a, b, left, center);//依然是分治的思想,类似快排
Msort(a, b, center + 1, right);
merge(a, b, left, center + 1, right);
}
}
void Mergesort(int a[], int n)//对大数据处理时常常要考虑到内存分配问题,所以要通过动态内存分配的方法来优化程序
{
int *tmp;
tmp = (int *) malloc(sizeof(int) * n);
if(tmp)
{
Msort(a, tmp, 0, n - 1);
free(tmp);//每次归并排序时都只需要一个临时内存空间来协助排序,所以当排序结束后可以将其释放
}
else
puts("Error! No free ram left!");
}
main()
{
int nums[100];
srand(time(NULL));
for(int i = 0; i < 100; i++)
nums[i] = rand() % 100;
for(int i = 0; i < 100; i++)
printf("%d ", nums[i]);
puts("\n-----------------------------------------------");
Mergesort(nums, 100);
for(int i = 0; i < 100; i++)
printf("%d ", nums[i]);
}
poj 2299:
http://poj.org/problem?id=2299
本题是merge sort的经典题目,因为merge sort也是通过小数组的两两比较来排序的,和bubble很像,所以虽然本题可以用bubble得出正确答案,但超时是无疑的。
解题思路:计算每次排序后数字位置的变化量,将其累加。
AC代码:
#include<stdio.h>
#include<stdlib.h>
long long count;
void merge(int a[], int tmp[], int s, int m, int e)
{
int ok = 0;
int f = m - 1, k = s, n = e - s + 1, inis = s;
while(s <= f && m <= e)
{
if(a[s] <= a[m])//临时数组tmp和原数组a是相同排序方式
{
tmp[k++] = a[s++];
}
else
{
count += abs(k - m);//只有当后面数列的数大于前面数列的数时才会互换,互换次数=abs(当前位-原位)
tmp[k++] = a[m++];
}
}
while(s <= f)
tmp[k++] = a[s++];
while(m <= e)
tmp[k++] = a[m++];
for(int i = 0; i < n; i++)//为了使tmp复制到a上,特意设置了inis变量
a[i + inis] = tmp[i+ inis];
}
void Msort(int a[], int tmp[], int s, int e)
{
int mid;
if(s < e)
{
mid = (s + e) / 2;
Msort(a, tmp, s, mid);
Msort(a, tmp, mid + 1, e);
merge(a, tmp, s, mid + 1, e);
}
}
void MergeSort(int a[], int n)
{
int *tmp;
tmp = (int *) malloc(sizeof(int) * n);
if(tmp)
{
Msort(a, tmp, 0, n - 1);
free(tmp);
}
}
main()
{
int n;
int *nums;
while(scanf("%d", &n) && n)
{
count = 0;
nums = (int *) malloc(sizeof(int) * n);
for(int i = 0; i < n; i++)
scanf("%d", &nums[i]);
MergeSort(nums, n);
printf("%lld\n", count);
}
}