一.希尔(Shell)排序法
/* Shell 排序法 */
#include <stdio.h>
void sort(int v[],int n)
{
int gap,i,j,temp;
for(gap=n/2;gap>0;gap /= 2) /* 设置排序的步长,步长gap每次减半,直到减到1 */
{
for(i=gap;i<n;i++)/* 定位到每一个元素 */
{
for(j=i-gap;(j >= 0) && (v[j] > v[j+gap]);j -= gap ) /* 比较相距gap远的两个元素的大小,根据排序方向决定如何调换 */
{
temp=v[j];
v[j]=v[j+gap];
v[j+gap]=temp;
}
}
}
}
二.二分插入法
/* 二分插入法 */
void HalfInsertSort(int a[], int len)
{
int i, j,temp;
int low, high, mid;
for (i=1; i<len; i++)
{
temp = a[i];/* 保存但前元素 */
low = 0;
high = i-1;
while (low <= high) /* 在a[low...high]中折半查找有序插入的位置 */
{
mid = (low + high) / 2; /* 找到中间元素 */
if (a[mid] > temp)/* 如果中间元素比但前元素大,当前元素要插入到中间元素的左侧 */
{
high = mid-1;
}
else/* 如果中间元素比当前元素小,但前元素要插入到中间元素的右侧 */
{
low = mid+1;
}
}/* 找到当前元素的位置,在low和high之间 */
for (j=i-1; j>high; j--)/* 元素后移 */
{
a[j+1] = a[j];
}
a[high+1] = temp; /* 插入 */
}
}
三.直接插入法
/*直接插入法*/
void InsertionSort(int input[],int len)
{
int i,j,temp;
for (i = 1; i < len; i++)
{
temp = input[i];/* 操作当前元素,先保存在其它变量中 */
for (j = i - 1;j>-1&&input[j] > temp ; j--) /* 从当前元素的上一个元素开始查找合适的位置 */
{
input[j + 1] = input[j]; /* 一边找一边移动元素 */
input[j] = temp;
}
}
}
四.带哨兵的直接排序法
/**
* 带哨兵的直接插入排序,数组的第一个元素不用于存储有效数据
* 将input[0]作为哨兵,可以避免判定input[j]中,数组是否越界
* 因为在j--的过程中,当j减小到0时,变成了input[0]与input[0]
* 自身进行比较,很明显这个时候说明位置i之前的数字都比input[i]小
* 位置i上的数字不需要移动,直接进入下一轮的插入比较。
*
*/
void InsertionSortWithPiquet(int input[],int len)
{
int i,j;
for (i = 2; i < len; i++)/* 保证数组input第一元素的存储数据无效,从第二个数据开始与它前面的元素比较 */
{
input[0] = input[i];
for (j = i - 1; input[j] > input[0] ; j--)
{
input[j + 1] = input[j];
input[j] = input[0]; /* input[j]一直都是排序的元素中最大的那一个 */
}
}
}