目的:
1.掌握能用分治法求解的问题应满足的条件;
2.加深对分治法算法设计方法的理解与应用;
3.锻炼学生对程序跟踪调试能力;
4.通过本次实验的练习培养学生应用所学知识解决实际问题的能力。
问题:
输入N个数对其进行归并排序。
解决策略:
分治法策略:
问题可以简化为在n个数里面寻找最大和最小值。
(1)将数据等分为两组(两组数据的个数可能相差1),目的是分别选取其中的最大(小)值。
(2)递归分解直到每组元素的个数<=2,则可以简单地找到其中的最大(小)值。
(3)回溯时合并子问题的解,在两个子问题的解中大者取大,小者取小,即合并为当前问题的解。
归并排序的过程是,将数组分为许多的组,即将数组元素多的数组分为数组元素少的数组,然后再将其合并。它的优点是,同时对多个数据进行对比排序,归并排序是分治法的典型应用。
分:体现在将数组分为小数组。
治:对排好序的数组进行合并。
代码实现:
#include<bits/stdc++.h>
using namespace std;
void Mergearray(int a[],int first,int mid,int last,int temp[]) //将两个有序数组合并排序
{
int i=first,j=mid+1;
int m=mid,n=last;
int k=0;
while(i<=m&&j<=n)
{
if(a[i]<a[j])
temp[k++]=a[i++];
else
temp[k++]=a[j++];
}
while(i<=m)
temp[k++]=a[i++];
while(j<=n)
temp[k++]=a[j++];
for(i=0;i<k;i++)
a[first+i]=temp[i];
}
void Mergesort(int a[],int first,int last,int temp[]) //将两个任意数组合并排序
{
if(first<last)
{
int mid=(first+last)/2;
Mergesort(a,first,mid,temp); //左边有序
Mergesort(a,mid+1,last,temp); //右边有序
Mergearray(a,first,mid,last,temp); //再将两个有序数组合并
}
}
bool MergeSort(int a[], int n)
{
int *p = new int[n]; //分配一个有n个int型元素的数组所占空间,并将该数组的第一个元素的地址赋给int *型指针p。
if (p == NULL)
return false;
Mergesort(a, 0, n - 1, p);
delete[] p;
return true;
}
int main()
{
int a[1000];
int n;
printf("请输入数的个数:\n");
scanf("%d",&n);
printf("请输入要排序的数列:\n");
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
MergeSort(a,n);
printf("排序结果为:");
for(int i=0;i<n;i++)
printf(" %d ",a[i]);
}
运行结果: