插入排序-(直接插入、折半插入、Shell排序)

import java.util.Arrays;
/**
 * 插入排序:直接插入排序、shell排序、折半插入排序
 * @author mk
 *
 */
public class InsertInSort
{
/*
*  直接插入排序:
*  第1趟将第2个元素开始,插入前面有序的序列,此时前面只有一个元素,当然是有序的
*  第2趟将第3个元素插入到前面有序的序列
*  第n-1趟将第n个元素插入到前面n-1个元素的有序序列
*  直接排序时间效率不高,最坏的情况下所有元素比较的总和为0+1+2+...n-1=o(n2).空间效率高
*  只需要缓存一个元素O(1).
*/
public static void sortDirectInsert(DataWrap [] datas)
{
for(int i=1; i<datas.length-1; i++)
{
DataWrap tmp = datas[i];// 保存待插入序列的值
// i索引处值比前面有序的序列值小,需要插入
if(datas[i].compareTo(datas[i-1]) < 0)
{
int j = i -1;
// 整体后移一位
for(; j>=0 && datas[j].compareTo(tmp)>0; j--) datas[j+1] = datas[j];
datas[j+1] = tmp;// 将tmp插入到合适的位置
}
System.out.println("第"+i+"趟排序:"+Arrays.toString(datas));                     
}
}

/*
* 折半插入,有名二分查找,效率更快找到插入位置
*/
public static void sortBinaryInsert(DataWrap [] datas)
{
for(int i=0; i<datas.length; i++)
{
DataWrap tmp = datas[i];
int low=0, high = i-1;
while(low <= high)
{
int mid = (low + high )/2;
// 如果tmp大于low~high中间值
if(tmp.compareTo(datas[mid]) > 0)
low = mid + 1;// 限制在索引大于中间元素的那一半查找
else
high = mid - 1;// 限制小于中间元素的那一半查找
}
// 将low到i的所有元素向后移动一位
for(int j = i; j > low; j--) datas[j] = datas[j-1];
datas[low] = tmp;
System.out.println("第"+i+"趟排序:"+Arrays.toString(datas));      
}
}

/*
* shell排序是Donald L.Shell 1959年发现并以他名字命名的
*/
public static void sortShell(DataWrap [] datas)
{
int arrayLength = datas.length;
int h = 1; //h变量保存可变增量
while(h <= arrayLength / 3) h = h * 3 + 1;//按h * 3 + 1得到增量序列的最大值
while(h > 0)
{
System.out.println("===h的值:" + h + "===");
for (int i = h ; i < arrayLength ; i++ )
{
DataWrap tmp = datas[i];//当整体后移时,保证data[i]的值不会丢失
//i索引处的值已经比前面所有值都大,表明已经有序,无需插入(i-1索引之前的数据已经有序的,i-1索引处元素的值就是最大值)
if (datas[i].compareTo(datas[i - h]) < 0)
{
int j = i - h;
//整体后移h格
for ( ; j >= 0 && datas[j].compareTo(tmp) > 0 ; j-=h) datas[j + h] = datas[j];
datas[j + h] = tmp;//最后将tmp的值插入合适位置
}
System.out.println("第"+i+"趟排序:"+Arrays.toString(datas)); 
}
h = (h - 1) / 3;
}
}
public static void main(String[] args)
{
DataWrap[] dws = { new DataWrap(10, ""), new DataWrap(5, ""),
new DataWrap(8, ""), new DataWrap(3, ""),new DataWrap(14, "") };
System.out.println("排序前:" + Arrays.toString(dws));
// sortDirectInsert(dws);
// sortBinaryInsert(dws);
sortShell(dws);
System.out.println("排序后:" + Arrays.toString(dws));
/*
* 测试结果
* 排序前:[10, 5, 8, 3, 14]
* 第1趟排序:[5, 10, 8, 3, 14]
* 第2趟排序:[5, 8, 10, 3, 14]
* 第3趟排序:[3, 5, 8, 10, 14]
* 排序后:[3, 5, 8, 10, 14]
*/
/* Shell 排序测试结果
* 排序前:[10, 5, 8, 3, 14]
* ===h的值:4===
* [10, 5, 8, 3, 14]
* ===h的值:1===
* 第1趟排序:[5, 10, 8, 3, 14]
* 第2趟排序:[5, 8, 10, 3, 14]
* 第3趟排序:[3, 5, 8, 10, 14]
* 第4趟排序:[3, 5, 8, 10, 14]
* 排序后:[3, 5, 8, 10, 14]
*/
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值