外面下雨不方便出去,就趁着这个机会又把之前学过的、用过的排序算法给整理了一下。重新回过头来看看,倒是捡起了不少遗忘的知识,勤整理、勤汇总果然不会错。
#include<stdio.h>
#include<stdlib.h>
/*插入类排序*/
void insertSort(int a[],int n) //直接插入排序
{
int i,j;
int temp;
//第一个元素(i=0)默认有序,故从第二个元素(i=1)开始找位置插入
for(i=1; i<n; ++i)
{
//首先将待排记录暂存在temp中,
//避免后续的边比较边移位操作导致数据覆盖而丢失
temp=a[i];
//对有序序列的元素(a[i]之前的元素),temp从后往前与其比较,
j=i-1;
//j>=0防越界
//如果大于待排关键字,则后移一位
while(j>=0&&temp<a[j])
{
a[j+1]=a[j];
--j; //更新j继续比较,直至temp>=a[i]
}
//直到找到第一个大于temp的元素,插入记录到j指示位置的后面
a[j+1]=temp;
}
}
void insertSort2(int a[],int n)
{
int i,j;
//待排记录存放在1~n-1 ,从第2个元素开始比较
for(i=2; i<n; i++)
{
//a[0]功能:备份(类似于上面的temp)、防越界 (类似于上面的j>=0)
a[0]=a[i];
j=i-1;
while(a[0]<a[j])
{
a[j+1]=a[j];
j--;
}
a[j+1]=a[0];
}
}
void binSort(int a[],int n)//折半插入排序
{
int low,high,mid;
int i,j,x;
//待排记录存放在0~n-1,low、high分别指向前i-1个有序元素的首末元素,
//从第3个元素(i=2)开始与mid所指向的元素作比较
for(i=2; i<n; i++)
{
x=a[i];//待插记录
low=0;
high=i-1;
while(low<=high) //1.确定插入位置
{
mid=(low+high)/2;
//每次都只与mid的左半边或右半边作比较,减少了比较次数
if(x<a[mid])
high=mid-1;
else
low=mid+1;
}
for(j=i-1; j>=low; --j) //2.记录后移
a[j+1]=a[j];
a[low]=x; //3.插入记录
}
}
void shellInsert(int a[],int n,int delta)
{
int i,j;
//从第1个子序列的第2个元素开始,顺序扫描整个待排序列,当
//前元素属于哪个序列就对其在哪个序列上进行直接插入排序
//delta+1表示第1个子序列的第2个元素下标
for(i=delta+1; i<n; i++)
if(a[i]<a[i-delta])
{
a[0]=a[i];//只备份,不监视
//此处只能拿j>0做监视哨,因为j的变化以delta为增量,而不是减1,
//只有delta等于1时才可实现以a[0]作监视
//从后往前,与当前元素所在序列且位于当前元素前的元素比较,
//寻找最终该插入的位置