7.9 排序——希尔排序

  今天是我的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<iostream>
#include<string>
#include<vector>
using namespace std;
int n,a[1000001];
long long cnt=0;
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]);
 }
}
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;
}
posted @ 2019-07-09 09:49  陈晓淞cxs  阅读(176)  评论(0编辑  收藏  举报