直接插入排序
#include<iostream>
using namespace std;
#define MAXSIZE 20
typedef struct{
int key;
int info;
}redtype;
typedef struct{
redtype a[MAXSIZE];
int length;
}sqlist;
sqlist stright(int b[],int len)
{
int i,j,k;
sqlist l;
for(i=0;i<len;i++)
{
j=i+1;
l.a[j].key=b[i];
if(j>=2)
{
if(l.a[j].key<l.a[j-1].key)
{
l.a[0]=l.a[j];
l.a[j]=l.a[j-1];
for(k=j-2;l.a[0].key<l.a[k].key;k--)
{
l.a[k]=l.a[k-1];
}
l.a[k+1]=l.a[0];
}
}
}
return l;
}
int main()
{
int b[10]={1,2,5,3,4,7,6,9,13,10};
sqlist l;
l=stright(b,10);
for(int i=1;i<11;i++)
{
cout<<l.a[i].key<<endl;
}
}
第0的位置为哨兵,第一个数插入第一个位置,从第二个数插入开始,如果比前面的大,就直接插入,否则:
1.先把数赋值给哨兵
2.把前一个数后移一位
3.从前前个数开始循环与哨兵比较,直到哨兵的值比它大或相等为止。同时不断地后移比哨兵大的树
4.将哨兵的数赋值给停下来的数的后一个数
5.从1号位置开始的就是直接插入排序的结果
折半插入排序
思想和直接插入一样,只不过把查找过程改成折半查找。
#include<iostream>
using namespace std;
#define MAXSIZE 20
typedef struct{
int key;
int info;
}redtype;
typedef struct{
redtype a[MAXSIZE];
int length;
}sqlist;
sqlist stright(int b[],int len)
{
int i,j,k,high,low,mid;
sqlist l;
l.a[1].key=b[0];
for(i=0;i<len;i++)
{
j=i+1;
if(j>=2)
{
high=j-1;
low=1;
l.a[0].key=b[i];
while(low<=high)
{
mid=(int)((high+low)/2);
if(l.a[0].key<l.a[mid].key)
high=mid-1;
else
low=mid+1;
}
//当插入的值比所有都大时,mid所指的是当前最大位,是不用后移的
for(k=j-1;k>=high+1;k--)
{
l.a[k+1].key=l.a[k].key;
}
l.a[high+1].key=l.a[0].key;
}
}
return l;
}
int main()
{
int b[10]={1,2,5,3,4,7,6,9,13,10};
sqlist l;
l=stright(b,10);
for(int i=1;i<11;i++)
{
cout<<l.a[i].key<<endl;
}
}
希尔排序
dk为序列增量。
例如,dk=2
序列[1,2,3,4,5]
子序列就是
1,3,5
2,4
对序列执行多个dk到dk=1,
每个dk进行直接插入排序。
#include<iostream>
using namespace std;
void shell(int (&b)[10],int len,int dk)
{
int sb;//哨兵
int i,j;
for(i=dk;i<len;i++)
{
if(b[i]<b[i-dk])
{
sb=b[i];
for(j=i-dk;j>0&&sb<b[j];j-=dk)
{
b[j+dk]=b[j];
}
b[j+dk]=sb;
}
}
}
int main()
{
int b[10]={1,2,5,3,4,7,6,9,13,10};
int dk[3]={5,2,1};
int i;
for(i=0;i<3;i++)
{
shell(b,10,dk[i]);
}
for(int i=0;i<10;i++)
{
cout<<b[i]<<endl;
}
}