排序算法之插入排序

一.总述


······在研究排序算法时,插入排序往往被作为入门算法来学习,我们今天就来看一下插入排序。近期我们再来慢慢研究冒泡排序、选择排序、希尔排序、快速排序以及堆排序。话不多说,下面进入今天的主题。
  首先我们要了解,插入排序算法又分成直接插入排序与折半插入排序两种,折半插入排序算法则是在直接插入排序的基础上加以了改进优化,我们先来看一下直接插入排序:

二.插入排序之直接插入排序

1.原理

插入排序的思想是将待排序数组分为有序区间以及无序区间,数组第一个元素为初始有序区间,其余为初始无序区间。然后,从无序区间中取第一位元素插入到有序区间内,按照“插入扑克牌”方式(习惯上从小到大)进行排序。以此方式,将所有无序区间元素插入到有序区间后,排序完成。
  下面来举个栗子:
  假设待排序的数据是数组A[0….n]。初始时,A[0]自成1个有序区,无序区为A[1….n]。在排序的过程中,依次将A[i] (i=1,2,….,n)从后往前插入到前面已排好序的子数组中的适当位置,当所有的A[i] 插入完毕,数组A中就包含了已排好序的输出序列。
  A [5] = { 3,6,4,1,5 }
  A[0] = 3 A[1] = 6 A[2] = 4 A[3] = 1 A[4] = 5
  排序过程(不同于此的折半插入在确定插入位置时做出了二分法的实现要求):
  第一趟排序后:[ 3 ] 6, 4, 1, 5
  第二趟排序后:[ 3 , 6 ] 4, 1, 5
  第三趟排序后:[ 3 , 4 , 6 ] 1, 5
  第四趟排序后:[ 1 , 3 , 4 , 6 ] 5
  第五趟排序后:[ 1 , 3 , 4 , 5 , 6 ]
  最后排序结果:
         1 3 4 5 6

2.代码实现

/**
*插入排序
*
*@author 夜雨声烦
*
*/
public class Insert {
// 传入参数为需要排序的随机数组
public static void insertionSort(int[] a) {
	int t;// 临时变量
	// 有序部分 增加
	for (int i = 1; i < a.length; i++) {
		// 将无序首元插入到有序数组中
		for (int j = i; j > 0; j--) {
			if (a[j] < a[j - 1]) {
				t = a[j - 1];
				a[j - 1] = a[j];
				a[j] = t;
			}
		}
	}
}

public static void main(String[] args) {
	int[] a = { 49, 38, 65, 97, 76 };
	insertionSort(a);
	for (int i = 0; i < a.length; i++) {
		System.out.print(a[i] + " ");
	}
  }
}

三.插入排序之折半插入排序((二分插入排序))

1.原理

折半插入排序是在直接插入的基础上加以改进,在将无序数据插入到有序区间时用采用二分法进行,所以又叫二分插入排序。用二分法确定应该插入的位置,每次取得有序区间中间位置的值进行比较,以此不断缩小范围,相比直接法寻找位置的次数少速度快,算法有一定的优化。

2.代码实现

/**
 * 算法实现部分提取
 * 
 * @param a
 *            待排序的数组
 */
private void binaryInsertSort(int[] a) {

	int n = a.length;
	int i, j;
	for (i = 1; i < n; i++) {
		// temp为本次循环待插入有序列表中的数
		int temp = a[i];
		int low = 0;
		int high = i - 1;
		// 寻找temp插入有序列表的正确位置,使用二分查找法
		// 每次缩减一半区间,较快寻找元素位置
		while (low <= high) {
			// 有序数组的中间坐标,此时用于二分查找,减少查找次数
			int mid = (low + high) / 2;
			// 若有序数组的中间元素大于待排序元素,则有序序列向中间元素之前搜索,否则向后搜索
			if (a[mid] > temp) {
				high = mid - 1;
			} else {
				low = mid + 1;
			}
		}

		for (j = i - 1; j >= low; j--) {
			// 元素后移,为插入temp做准备
			a[j + 1] = a[j];
		}
		// 插入temp
		a[low] = temp;
	}
}

写在最后的话

由于最近才开始学习写博文(之前都是作为笔记随笔来简要记录的,丑的一匹),博客的格式和内容都无法保证,但我会慢慢改正自己,还有很多的不足都是自己长期以来都从未意识到的,so也希望大佬前辈们能够耐心监督并提出宝贵的建议,我一定会吸取教训慢慢改正自己!!!在此献出自己的膝盖QAQ!!!

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值