排序专题之插入排序

来源:互联网 发布:阿里云报价单 编辑:程序博客网 时间:2024/06/15 11:56

根据书本上的描述,插入排序主要学了两种,一个是直接插入排序,一个

是shell 排序,shell排序是建立在直接插入排序的基础上的一个类似于优化

的排序,在某些情况下可以减小时间的复杂度。还加上一个折半排序,有带二分的思想:



直接插入排序::



#include<iostream>using namespace std;int main(){int n;int s[10];cin>>n;int i,j;for(i=0;i<n;i++){cin>>s[i];}int t;for(i=0;i<n;i++){t=s[i];j=i-1;while(j>0&&t<s[j]){s[j+1]=s[j];j--; }s[j+1]=t;}for(i=0;i<n;i++){cout<<s[i]<<"  ";}return 0;}//时间代价为n*n




shell排序的方法主要是利用插入排序的性质来,对直接全部插入排序

之前的序列进行一个缩小区间的一个预处理。将
原始序列分为更大,更有序的子序列,分别进行插入排序,

重复下去,直到最后的间距变为1,再进行整体的一个插入排序。
也称缩小增量排序法。每次缩小的增量以除以2来选择。即每次通过增量

,可以把s[i]和s[i-t]进行比较,t为增量大小。shell排序不是着眼于相邻的

记录来进行比较和交换,而是对那些不相邻的记录进行比较和交换。



代码如下:


#include<iostream>using namespace std;void molshell(int a[],int n,int delta){int i,j;for(i=delta;i<n;i+=delta){for(j=i;j>=delta;j-=delta){if(a[j]<a[j-delta]){int t=a[j];a[j]=a[j-delta];a[j-delta]=t;}}}}void shellsort(int a[],int n){int i,delta;for(delta=n/2;delta>0;delta/=2){for(i=0;i<delta;i++){molshell(&a[i],n-i,delta);}}molshell(a,n,1);}int main(){int n;int s[10];while(cin>>n){int i,j,k;for(i=0;i<n;i++){cin>>s[i];}shellsort(s,n);for(i=0;i<n;i++){cout<<s[i]<<" ";}cout<<endl;}return 0;}






采用折半插入排序法,可减少关键字的比较次数。每插入一个元素,

需要比较的次数最大为折半判定树的深度,
如插入第i个元素时,设i=2j,则需进行log2i次比较,

因此插入n-1个元素的平均关键字的比较次数为O(nlog2n)。 
 虽然折半插入排序法与直接插入排序法相比较,

改善了算法中比较次数的数量级,但其并未改变移动元素的时间耗费,
所以折半插入排序的总的时间复杂度仍然是O(n2)。 


void    BinSort (RecordType  r[],int length)/*对记录数组r进行折半插入排序,length为数组的长度*/{for (  i=2  ; i<=length ; ++i )   {   x= r[i];low=1;  high=i-1;      while (low<=high )                  /* 确定插入位置l */       {  mid=(low+high) / 2;         if (  x.key< r[mid].key   )    high=mid-1;         else   low=mid+1;}      for (  j=i-1  ; j>= low; --j )   r[j+1]= r[j];         /*  记录依次向后移动 */          r[low]=x;                                                       /* 插入记录 */    }} 





0 0
原创粉丝点击