输入:N个数<a1,a2,a3....an>
输出:输入的一个有序排列(非升序或者非降序)<b1,b2,b3.....bn>
算法:从时间复杂度来分析,插入排序算法的O(n^2)和合并排序算法的O(nlogn),当数据量变大的时候,显然合并排序算法比较快速。但是对于小规模的数据,使用插入排序还是很快速的。现在添加一个参数k,将原来的N个数划分为N/k个小数组,在小数组内进行插入排序后,再将这些小数组进行合并排序。这样分治法的可直接解决的问题的规模就由1上升为k个。
代码:
#include<iostream>
#include<cmath>
using namespace std;
//对含有不超过k个元素的小数组插入排序,此次排序为就地排序。
//数组A的一部分含有n个元素,开始下标为start
void insertSort(int A[],int n,int start)
{
int j;
int i;
int key;
for(j=start;j<start+n;j++)
{
key = A[j];
i = j-1;
while(i >=0 && A[i]>key)
{
A[i+1]=A[i];
i--;
}
A[i+1]=key;
}
}
//将下标为[p....q]和[q+1....r]的两个有序数组进行合并
void merge(int *A,int p,int q,int r)
{
int n1 = q-p+1;
int n2 = r-q;
int i ;
int j;
int *L = new int[n1];
int *R = new int[n2];
for(i = 0; i < n1;i++)
{
L[i] = A[p+i];
}
for(j = 0;j < n2;j++)
{
R[j]=A[q+j+1];
}
i = 0;
j = 0;
int k = p;
while(i<n1 && j<n2)
{
if(L[i] < R[j])
{
A[k]= L[i];
i++;
k++;
}
else
{
A[k] = R[j];
j++;
k++;
}
}
while (i < n1)
{
A[k] = L[i];
i++;
k++;
}
while(j< n2)
{
A[k] = R[j];
j++;
k++;
}
delete [] L;
delete [] R;
}
//合并排序算法算法
//当划分小于等于k个元素时就停止划分,先插入排序,后合并
void mergeSort(int *A ,int p ,int r,int k)
{
int q ;
if(p<r)
{
q = (p+r)/2;
if(q-p+1 <=k)
{
insertSort(A,q-p+1,p);
}
else
{
mergeSort(A,p,q,k);
}
if(r-q <=k)
{
insertSort(A,r-q,q+1);
}
else
{
mergeSort(A,q+1,r,k);
}
merge(A,p,q,r);
}
}
int main()
{
int n;
int k;
cout << "How many numbers do you want to sort? " << endl;
cin >> n;
int *A = new int [n];
for(int i = 0;i < n;i++)
{
cin >> A[i];
}
k=log(n);
mergeSort(A,0,n-1,k);
for(int i = 0;i<10;i++)
{
cout<<A[i]<<endl;
}
return 0;
}