选择排序、插入排序、希尔排序

选择排序

工作原理是从待排序的数据元素中选出最小(或最大)的一个元素,并与第一个数交换位置,然后选择剩下数组中最小的数,放到数组的第二个位置,
一次类推。
图解过程如下:

选择排序特点是:
1、运行时间和数组内容无关:我们会发现,即使是一个已经排序好的数组去使用选择排序,运行的时间与随机的数组排序时间居然一样长
2、移动的数据少:数组的交换次数和数组大小是线性关系。

/**
 * 选择排序 每次选择剩下数组中最小的数,然后与剩下数组最前面的数交换位置,直到结束。
 * 
 * @author xiaoqi
 *
 */
public class Selection {

	public static void sort(int[] a) {
		for (int i = 0; i < a.length; i++) {
			int min = i;// min为最小值的下标
			//找出剩余数组的最小值
			for (int j = i + 1; j < a.length; j++) {
				if(a[min] > a[j]){
					min = j;
				}
			}
			//交换位置
			int temp = a[i];
			a[i] = a[min];
			a[min] = temp;
		}
	}

}


插入排序

插入排序就如同我们打牌一样,按照顺序把每张牌插入一个已经排好序的数组中,剩余的数组右移即可。
图解如下:
特点,插入排序所需时间与数组的初识顺序相关,通过这点我们知道,它的运行效率是要高于选择排序的。其比较适合部分有序和规模中小的数组。
/**
 * 插入排序 如同打牌一样,将剩下数组的第一个插入到前面已经排好序的数组中,然后后移插入位置到原位置的数组一位 特别适合有一定顺序的数组
 * 
 * @author xiaoqi
 *
 */
public class Insertion {

	/**
	 * 将a[i]取出,然后从a[i-1]的位置开始从已经排序好的数组的最后一个位置开始向左(依次到第0个位置)比较,大于就交换位置
	 * 
	 * 通过交换位置的方式向右移动
	 * @param a
	 */
	public static void sort2(int[] a) {
		for (int i = 1; i < a.length; i++) {
			for (int j = i; j > 0; j--) {
				if (a[j] < a[j-1]) {
					int temp = a[j-1];
					a[j-1] = a[j];
					a[j] = temp;
				}
			}
		}
	}
}


希尔排序

希尔排序是对插入排序的一种优化。我们知道,插入排序是适合部分有序的数组,这样就可以使移动的数组尽量的小。而希尔排序就是先把一个数组变成“部分有序”,再进行插入排序,从而得到结果。他的思想是设置一个h,通过插入排序,让数组中任意间隔h的元素都是有序的,然后缩小h的值,再排序,直到h为1。因此它的效率取决于h的选取。
图解:

/**
 * 希尔排序 是插入排序的一种改进,它的空间复杂度取决于一个常数因子,但是小于插入排序。
 * 思想:把数组分为间隔为h的h个数组,然后分别插入排序,再把分为h/k(k>1)个数组,再插入排序,直到h为1。
 * @author xiaoqi
 *
 */
public class Shell {
	public static void sort(int[] a){
		int N = a.length;
		int h = 1;
		//假设这个常数因子是 d = 1/3
		//先得到一个h/d + 1大于 数组长度的最小值
		while(h < N/3){
			h = 3 * h + 1;
		}
		//进行插入排序直到h为1
		while(h >= 1){
			//每个数组间隔为h,进行插入排序
			for(int i=h;i< N;i++){
				for(int j = i;j >= h;j -= h){
					if(a[j] < a[j-h]){
						int temp = a[j];
						a[j] = a[j-h];
						a[j-h] = temp;
					}
				}
			}
			//缩小h
			h = h /3;
		}
		SortTest.show();
		SortTest.isSorted(a);
	}
}




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值