排序专题之插入排序
Posted 纯纯的心儿
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了排序专题之插入排序相关的知识,希望对你有一定的参考价值。
根据书本上的描述,插入排序主要学了两种,一个是直接插入排序,一个
是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; /* 插入记录 */
以上是关于排序专题之插入排序的主要内容,如果未能解决你的问题,请参考以下文章