阿布学排序之直接插入排序


/**
 * 需求:直接插入排序
 * 思想:每次将一个待排序的记录按其关键字大小插入到前面已经排好序的子序列中的适当位置,直到全部记录插入完成为止
 * 步骤:设数组为a[0..n-1]
 * 1、初始时,a[0]自成一个有序区,无序区为a[1...n-1]。令i=1
 * 2、将a[i]并入到当前的有序区a[0...i-1]中形成a[0...i]的有序区间
 * 3、i++并重复第二步直到i==n-1,排序完成
 * @author AbuGe
 *
 */
public class InsertSortDemo 
{
	//方法1
	public static void insertSort1(int[] array)
	{
		int i, j, k;
		int len = array.length;
		for(i = 1; i < len; i++)//从下标1开始向后遍历
		{
			for(j = i; 0 <= j; j--)//将i与i之间的数据进行比较,找到比i下标对应的数据小的下标
			{
				if(array[j] < array[i])
				{
					break;
				}
			}
			
			//此时判断j的下标是否是i-1,如果是就不用交换了
			if(j != i - 1)
			{
				int tmp = array[i];
				for(k = i - 1; k > j; k--)
				{
					array[k + 1] = array[k];
				}
				//此时k指向的是j的位置,这也是i应该存放的位置
				array[k + 1] = tmp;
			}
		}
	}
	//-----------------------------------------------------
	//方法2
	/**
	 * 优化:
	 * 思路:将搜索和后移这两个步骤合并,即每次array[i]和array[i-1]比较,如果array[i] > array[i - 1]说明array[0...i]也是有序的,无须调整,否则令
	 * j = i, tmp = array[i],然后同时进行搜索和后移,当有数据array[j] < array[i]时就停止,将tmp放到array[j+1]
	 * @param array
	 */
	public static void insertSort2(int[] array)
	{
		int i, j;
		int len = array.length;
		for(i = 1; i < len; i++)
		{
			if(array[i] < array[i - 1])
			{
				int tmp = array[i];
				for(j = i - 1; j >= 0 && array[j] > tmp; j--)//将i之前比array[i]大的元素后移
				{
					array[j + 1] = array[j];
				}
				
				array[j + 1] = tmp;
			}
		}
	}
	//---------------------------------------------------
	//方法3
	/**
	 * 改用数据交换代替数据后移
	 * @param 
	 */
	public static void insertSort3(int[] array)
	{
		int len = array.length;
		for(int i = 1; i < len; i++)
		{
			for(int j = i - 1; j >= 0 && array[j] > array[j + 1]; j--)
			{
				swap(array, j, j + 1);
			}
		}
	}
	
	//交换数据
	public static void swap(int[] array, int a, int b)
	{
		int tmp = array[a];
		array[a] = array[b];
		array[b] = tmp;
	}
	public static void main(String[] args)
	{
		int[] a = {3, 4, 6, 2, 8, 4, 1};
		for(int i : a)
		{
			System.out.print(i + "\t");
		}
		//insertSort1(a);
		//insertSort2(a);
		insertSort3(a);
		System.out.println();
		for(int i : a)
		{
			System.out.print(i + "\t");
		}
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值