今天是我的21周岁生日,就自己祝福自己生日快乐吧,一大早就来到了学校图书馆进行自己一天的编程学习,高兴的是刚刚收到了几位编程大佬的祝福,作为报答,我便为大家讲解一道特殊的排序算法——希尔排序吧,而且接下来的几道题我会挑出从classstack上找的几道比较有代表性的入门组题目来为大家进行详细的讲解,帮助入门组的同学们快速提升。
题目描述:
我们在插入排序法的基础上进一步发挥,将包含n个整数的数列A通过下述程序进行升序排列
void selectionsort(int A[],int N,int g){
for(int i=g;i<N;i++){
int v=A[i];
int j=i-g;
while(j>=0&&A[j]>v){
A[j+g]=A[j];
j-=g;
cnt++;
}
A[j+g]=v;
}
}
vector<int> G;
void shellsort(int N,int A[]){
for(int i=1;;){
if(i>n) break;
G.push_back(i);
i=i*3+1;
}
for(int i=G.size()-1;i>=0;i--){
selectionsort(A,N,G[i]);
}
}
insertionsort(A,n,g)是仅以间隔为g的元素为对象进行的插入排序。
shellSort(A,n)则是 insertionSort(A,n,g)的循环,并在每轮循环后逐渐
缩小g的范围。这种排序方法称为希尔排序法。
A作为输入数据,让程序输出伪代码中的m、m个整数G1(i=0,1,…,m-1)以及按
升序排列后的数列A。另外,输出必须满足以下条件。
1.1≤m≤100
2.0≤G≤n
3.cnt的值不超过「n137
入第1行输入整数n。接下来n行输入n个整数A(i=0,1,…,n-1)
输出第1行输出整数m,第2行输出m个整数G(i=0,1,…,m-1),用空格隔开。
第3行在使用G的程序执行完毕后输出cnt的值。
接下来n行输出排序完毕的A,(i=0,1,…,n-1)。
本题对于1个输入数据会有多个解答,因此所有满足条件的输出皆视为正确。
限制:
1≤n≤1000000
0≤A,≤10°
输入示例
5
5
1
4
3
2
输出示例
2
4 1
3
1
2
3
4
5
题解代码:
#include<string>
#include<vector>
using namespace std;
int n,a[1000001];
long long cnt=0;
for(int i=g;i<N;i++){
int v=A[i];
int j=i-g;
while(j>=0&&A[j]>v){
A[j+g]=A[j];
j-=g;
cnt++;
}
A[j+g]=v;
}
}
vector<int> G;
void shellsort(int N,int A[]){
for(int i=1;;){
if(i>n) break;
G.push_back(i);
i=i*3+1;
}
for(int i=G.size()-1;i>=0;i--){
selectionsort(A,N,G[i]);
}
}
int main(){
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
shellsort(n,a);
printf("%d\n",G.size());
for(int i=G.size()-1;i>=0;i--){
printf("%d ",G[i]);
}printf("\n");
printf("%lld\n",cnt);
for(int i=0;i<n;i++){
printf("%d\n",a[i]);
}
return 0;
}