您的位置:首页 > 其它

排序之插入排序

2017-12-03 16:58 106 查看
/*

名称:直接插入排序、折半插入排序、希尔排序

说明:本程序比较了插入排序的几种方法。

(1)、直接插入排序:

其适用于顺序存储和链式存储的线性表。它的时间复杂度为O(N2),主要花在比较和移动元素上。

(2)、折半插入排序:

这是在(1)中的方式上做了一点小改变,因为已经排序完成的序列是有序的(好像是废话) 所以每次比较时利用折半的方式,不用挨个比较。它减少了比较的时间。对于元素的移动, 对于(1)来说,它是边比较边移动元素的;而折半插入是找到指定位置后,统一移动元素。元素的总的移动次数并没有改变。所以其时间复杂度也是O(N2)

它是一个稳定的排序算法。

(3)、shell排序:

这是采用分治的思想。把整个序列分为若干个子序列,每次对若干个自序列进行排序。最终在对整体进行一次排序。事实证明,它确实能够大大提高排序的速度。

在本人的机器上进行测试,十万个随机数据,前两种方法大概都用了7s多,可shell排序用了1秒还不到。

它不是一个稳定的算法.

*/

//直接插入排序,n代表元素个数,从elem的下标为1开始存储
void InsertSortDir(int elem[],int n)
{
int i = 0, j = 0;
for( i = 2;i<=n;++i)
{

if(elem[i] < elem[i-1])     //如果当前元素小于前面的元素,说明需要比较前移
{
elem[0] = elem[i];      //elem【0】用作哨兵,不实际存储元素

for(j = i-1; elem[0]<elem[j]; --j)      //找到当前元素在此次排序中的位置
elem[j+1] = elem[j];

elem[j+1] = elem[0];
}
}
}


//折半插入排序
void InsertSortBin(int elem[],int n)
{
int i = 0,j = 0;
int high = 0,low = 0,mid = 0;

for(int i = 2;i <= n;++i)
{
if(elem[i] < elem[i-1])         //判断是否需要插入
{
low = 1;
high = i-1;
elem[0] = elem[i];

//寻找待插入位置
while(low <= high)
{
mid = (low + high) / 2;

if(elem[mid] > elem[0])
high = mid -1;
else
low = mid + 1;

}

//向后移动元素
for(j = i; j > high+1;--j)
elem[j] = elem[j-1];

elem[high+1] = elem[0];     //将当前结点插入指定位置

}
}

}


//shell排序
void ShellSort(int elem[],int n)
{
int dk = 0,i = 0,j = 0;
for( dk = n/2; dk >= 1;dk = dk / 2)      //dk为递增序列,其值每次减少一半
{
for(i = dk+1; i<=n;++i)     //对于每个序列进行排序
{
if(elem[i] < elem[i-dk])    //判断当前的自序列是否需要排序
{
elem[0] = elem[i];      //elem暂存当前元素
for( j = i - dk; j > 0 && elem[j] > elem[0];j = j-dk)        //和插入排序有点不同的是,这里的判断条件多了一个j>0,因为每次的递增序列dk不一定是1
elem[j+dk] = elem[j];

elem[j+dk] = elem[0];
}
}
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐