#include<stdio.h>
void ShellInsertSort(int r[],int n,int dk)
{
int i;
for(i=dk;i<n;++i)
{
if(r[i]<r[i-dk])
{
int j = i-dk;
int x = r[i];
while(x<r[j] && j>=0)
{
r[j+dk] = r[j];
j = j-dk;
}
r[j+dk] = x;
}
}
}
void ShellSort(int r[],int n)
{
int dk;
dk=n/2;
while(dk>=1)
{
ShellInsertSort(r,8,dk);
dk=dk/2;
}
}
void print(int r[],int n)
{
int i;
for(i=0;i<n;++i)
{
printf("%3d",r[i]);
}
printf("\n");
}
void InsertSort(int a[] ,int n)
{
printf("InsertSort:\n");
int i,j,t;
for(i=1;i<n;++i)
{
if(a[i]<a[i-1])
{
t=a[i];
for(j=i-1;t<a[j];--j)
{
a[j+1]=a[j];
}
a[j+1]=t;
}
}
}
void BinInsertSort(int a[],int n)
{
printf("BinInsertSort:\n");
int i,j,t;
int low,high,mid;
for(i=1;i<n;++i)
{
t=a[i];
low=0;
high=i-1;
mid=0;
while(low<=high)//BinSearch: 查找结束后high的值为(若t的值在查找的数组里,则high为t值对应元素的下标,若t不在数组里,则high为比t小的第一个元素的下标)
{
mid=(low+high)/2;
if(t<a[mid])
{
high=mid-1;
}
else
{
low=mid+1;
}
}
for(j=i-1;j>=high+1;--j)
a[j+1]=a[j];
a[high+1]=t;
}
}
void TwoWaysInsertSort(int *a,int n)
{
printf("Two Ways InsertSort:\n");
int temp[n];
int last,first,i,k;
temp[0]=a[0];
first=last=0;
for(i=1;i<n;++i)
{
if(a[i]<temp[first])
{
first=(first-1+n)%n;
temp[first]=a[i];
}
else if(a[i]>temp[last])
{
last=(last+1+n)%n;
temp[last]=a[i];
}
else
{
k=(last+1+n)%n;
while(temp[(k-1+n)%n]>a[i])
{
temp[(k+n)%n]=temp[(k+n-1)%n];
k=(k-1+n)%n;
}
temp[(k-1+n)%n]=a[i];
last=(last+1+n)%n;
}
}
for(k=0;k<n;++k)
{
a[k]=temp[k];
}
}
int main()
{
int a[8]={3,1,5,7,2,4,9,6};
printf("before ShellSort:\n");
print(a,8);
ShellSort(a,8);
printf("after ShellSort:\n");
print(a,8);
InsertSort(a,8);
print(a,8);
BinInsertSort(a,8);
print(a,8);
TwoWaysInsertSort(a,8);
print(a,8);
return 0;
}
void ShellInsertSort(int r[],int n,int dk)
{
int i;
for(i=dk;i<n;++i)
{
if(r[i]<r[i-dk])
{
int j = i-dk;
int x = r[i];
while(x<r[j] && j>=0)
{
r[j+dk] = r[j];
j = j-dk;
}
r[j+dk] = x;
}
}
}
void ShellSort(int r[],int n)
{
int dk;
dk=n/2;
while(dk>=1)
{
ShellInsertSort(r,8,dk);
dk=dk/2;
}
}
void print(int r[],int n)
{
int i;
for(i=0;i<n;++i)
{
printf("%3d",r[i]);
}
printf("\n");
}
void InsertSort(int a[] ,int n)
{
printf("InsertSort:\n");
int i,j,t;
for(i=1;i<n;++i)
{
if(a[i]<a[i-1])
{
t=a[i];
for(j=i-1;t<a[j];--j)
{
a[j+1]=a[j];
}
a[j+1]=t;
}
}
}
void BinInsertSort(int a[],int n)
{
printf("BinInsertSort:\n");
int i,j,t;
int low,high,mid;
for(i=1;i<n;++i)
{
t=a[i];
low=0;
high=i-1;
mid=0;
while(low<=high)//BinSearch: 查找结束后high的值为(若t的值在查找的数组里,则high为t值对应元素的下标,若t不在数组里,则high为比t小的第一个元素的下标)
{
mid=(low+high)/2;
if(t<a[mid])
{
high=mid-1;
}
else
{
low=mid+1;
}
}
for(j=i-1;j>=high+1;--j)
a[j+1]=a[j];
a[high+1]=t;
}
}
void TwoWaysInsertSort(int *a,int n)
{
printf("Two Ways InsertSort:\n");
int temp[n];
int last,first,i,k;
temp[0]=a[0];
first=last=0;
for(i=1;i<n;++i)
{
if(a[i]<temp[first])
{
first=(first-1+n)%n;
temp[first]=a[i];
}
else if(a[i]>temp[last])
{
last=(last+1+n)%n;
temp[last]=a[i];
}
else
{
k=(last+1+n)%n;
while(temp[(k-1+n)%n]>a[i])
{
temp[(k+n)%n]=temp[(k+n-1)%n];
k=(k-1+n)%n;
}
temp[(k-1+n)%n]=a[i];
last=(last+1+n)%n;
}
}
for(k=0;k<n;++k)
{
a[k]=temp[k];
}
}
int main()
{
int a[8]={3,1,5,7,2,4,9,6};
printf("before ShellSort:\n");
print(a,8);
ShellSort(a,8);
printf("after ShellSort:\n");
print(a,8);
InsertSort(a,8);
print(a,8);
BinInsertSort(a,8);
print(a,8);
TwoWaysInsertSort(a,8);
print(a,8);
return 0;
}
简单插入排序:平均时间复杂度是大O(n^2), 稳定的排序,
二分查找插入排序: 在确定一个元素应当插入的位置时,没有从待插入元素的前一个位置开始一个一个的比较移动元素,直至找到待插入元素插入.是先通过二分查找找到待插入元素因该去的位置,然后依次移动元素,这就减少了比较的次数.
2-路插入排序:是借助了一个辅助空间temp,和两个变量first ,last来标记当前临时数组中存放的元素的最小数和最大数所在数组的位置. 把这个数组想象成为一个环形空间,首先将a数组中的第一个元素放入辅助数组中,并标记为first ,last, 然后依次处理剩余a数组中的元素,若下一个元素比first元素还小,则把这个元素插入到first的前一个位置,并更改first的值为这个元素的下标,如果下一个元素比last还大,则将这个元素插入到last后面位置,并修改last;如果下一个元素同时比fisrst大,且比last小,则从last位置开始寻找这个元素应该插入的位置.2-路插入排序是减少了元素移动的次数,二分查找排序是减少了比较大小的次数(.2-路要注意的是:想象数组为环形空间,是要通过数组元素的下标来实现)
希尔排序: 时间复杂度O(nlgn) 是不稳定的排序方法. 又称为: 减少增量排序算法. 确定一个dk(这个值要小于元素个数大于等于1)每次对数组中的相差dk个位置的元素进行插入排序, 然后将这个值每次减少一半(这里不一定必须时一半,看情况)继续对这个数组中所有相差为dk的元素为一组进行排序....直至dk减之1.