插入类排序算法

复习八大基础排序算法。分类:
1. 插入类(直接插入、希尔排序)
2. 选择类(直接选择、堆排序)
3. 交换类(冒泡排序、快速排序)
4. 归并排序
5. 还有外部排序(桶排序?)

直接插入

首先明确定义,比如插入排序如果对定义不够清楚,有可能写着写着就掺和进了选择排序(排序结果不一定错,但是过程“变质了”)。

直接插入排序(Insertion Sort)的基本思想是:每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子序列中的适当位置,直到全部记录插入完成为止。

设数组为a[0…n-1]。

  1. 初始时,a[0]自成1个有序区,无序区为a[1..n-1]。令i=1

  2. 将a[i]并入当前的有序区a[0…i-1]中形成a[0…i]的有序区间

  3. i++并重复第二步直到i==n-1。排序完成

下面给出严格按照定义书写的代码(由小到大排序):

public static void insertionSort1(Comparable[] a) {
	for (int i = 1; i < a.length; i++) {
		// search
		int j;
		for (j = i - 1; j >= 0; j--)
			if (less(a[j], a[i]))	 break;  // a[j] < a[i]
		// insert (shift then put)
		if (j != i - 1) {
			Comparable temp = a[i];
			for (int k = i; k > j + 1; k--)
				a[k] = a[k - 1];
			a[j + 1] = temp;
		}
	}
}

这个代码比较长,可以进行改写,将搜索和数据后移两个步骤合并。即:用temp记录a[i]的值,每次a[j]都和a[i]比较,如果a[i] < a[j]说明a[0…i]也是有序的,无须调整;否则就一边将数据a[j]后移一边向前搜索,直到a[j]<a[i]才停止,并将temp放到a[j+1]处。

public static void insertionSort2(Comparable[] a) {
	for (int i = 1; i < a.length; i++) {
		// insert while search
		Comparable temp = a[i];
		int j;
		for (j = i - 1; j >= 0 && less(a[i], a[j]); j--) {
			a[j + 1] = a[j];
		}
		a[j + 1] = temp;
	}
}

再对将a[i]插入到前面a[0…i-1]的有序区间所用的方法进行改写,用数据交换代替数据后移。如果a[j]前一个数据a[j-1] > a[j],就交换a[j]和a[j-1],再j--直到a[j-1] <= a[j]。这样也可以实现将一个新数据新并入到有序区间。

public static void insertionSort3(Comparable[] a) {
	for (int i = 1; i < a.length; i++) {
		for (int j = i - 1; j >= 0 && less(a[j+1], a[j]); j--)
			exch(a, j, j+1);
	}
}

希尔排序

public static void shellSort1(Comparable[] a) {
	int[] incs = {33936, 13776, 4592, 1968, 861, 336, 112, 48, 21, 7, 3, 1};
	for (int d = 0; d < incs.length; d++) {
		int h = incs[d];
		if (a.length > h) {
			for (int k = 0; k < h; k++) {
				/*
				 * 对每一组作直接插入排序( insertionSort 只有一组,对应的 h = 1, k = 0 )
				 */
				for (int i = k + h; i < a.length; i += h) 
					for (int j = i - h; j >= k && less(a[j + h], a[j]); j -= h)
						exch(a, j + h, j);					
			}	
		}
	}

}

public static void shellSort2(Comparable[] a) {
	int[] incs = {33936, 13776, 4592, 1968, 861, 336, 112, 48, 21, 7, 3, 1};
	for (int d = 0; d < incs.length; d++) {
		int h = incs[d];
		if (a.length > h) {
			for (int i = h; i < a.length; i++) 
				for (int j = i - h; j >= 0 && less(a[j + h], a[j]); j -= h)
					exch(a, j + h, j);
		}
	}

}

posted @ 2016-04-17 22:39  SmartJuneThx  阅读(165)  评论(0编辑  收藏  举报