插入排序和希尔排序

概述

Java中排序算法是非常重要的一部分,这里简单分析下插入排序和希尔排序的实现思路及其代码实现。

常见排序算法时间复杂度表

排序算法平均时间复杂度最差情形稳定度额外空间备注
冒泡排序O(n^2)O(n^2)稳定O(1)n小时较好
插入排序O(n^2)O(n^2)稳定O(1)n小时较好
选择排序O(n^2)O(n^2)不稳定O(1)n小时较好
快速排序O(nlogn)O(n^2)不稳定O(nlogn)n大时较好
希尔排序O(nlogn)O(n^s)1 < s < 2不稳定O(1)n大时较好
归并排序O(nlogn)O(nlogn)稳定O(1)n大时较好
堆排序O(nlogn)O(nlogn)稳定O(1)n大时较好
基数排序O(nlogn)OlogrBO(n)O(n)B为真数(0-9),r为基数个十白

插入排序

插入排序(insertion Sorting)基本思想:把n个待排序的元素看作成,一个有序表,和一个无序表,
开始时有序表只有一个元素,无序表中有n-1个元素。排序过程中,每次从无序表中取出一个元素,将其与有序表中进行比较,将其插入在有序表中合适的位置。

插入排序图解

插入排序图解

插入排序代码实现
public class InsertSort {
	public static void insertSort(int[] arr) {
		if (arr == null || arr.length) {
			throw new IllegalArgumentException();
		}
		for (int i = 1; i < arr.length; i++) {
			// 定义待插入的数
			int insertValue = arr[i];
			// 定义待插入的位置
			int insertIndex = i - 1;

			// 如果插入的值小于他前一个值说明还没有找到这样的位置,并将前一个值,向后移动
			while (insertIndex >= 0 && insertValue < arr[insertIndex]) {
				arr[insertIndex + 1] = arr[insertIndex];
				insertIndex--;
			}
			// 退出循环说明已经找到插入的位置
			arr[insertIndex] = insertValue;
		}
	}
}
简单插入排序存在的问题

假如我们有一个这样的数组{2, 3, 4, 5, 1},此时我们需要插入的值为1,那么执行的过程为。

  1. {2, 3, 4, 5, 5}
  2. {2, 3, 4, 4, 5}
  3. {2. 3, 3, 4, 5}
  4. {2, 2, 3, 4, 5}
  5. {1, 2, 3, 4, 5}
    很显然为了插入一个1,我们一共移动了4次,这种显然有点浪费效率了,下面我们使用更加牛皮的排序方法,希尔排序

希尔排序

希尔排序简单介绍

希尔排序是希尔(Donald Shell)于1959年提出的一种排序算法。希尔排序也是一种插入排序,他是简单插入排序经过改进之后的一种更高的版本,也称为缩小增量排序。

希尔排序基本思想

希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。

希尔排序图解

希尔排序图解

希尔排序交换法
public class ShellSort {
	public static void shellSort(int[] arr) {
		if (arr == null || arr.length <= 0) {
			throw new IllegalArgumentException();
		}
		int temp = 0;
		for (int gap = arr.length/2; gap > 0;gap /= 2;) {
			for (int i = gap;i < arr.length;i++) {
				for (int j = i - gap;i >= 0 ; j -= gap) {
					if (arr[j] > arr[j + gap]) {
						temp = arr[j];
						arr[j] = arr[j + gap];
						arr[j + gap] = temp;
					}
				}
			}
		}
	}
}
希尔排序位移法
public class ShellSort {
	public static void shellSort(int[] arr) {
		if (arr == null || arr.length <= 0) {
			throw new IllegalArgumentException();
		}
		for (int gap = arr.length/2; gap > 0;gap /= 2;) {
			for (int i = gap;i < arr.length;i++) {
				int insertValue = arr[i];
				int insertIndex = i;

				while (insertIndex - gap >= 0 && insertValue < arr[insertIndex - gap]) {
					arr[insertIndex] = arr[insertIndex - gap];
					insertIndex  -= gap;
				}
				
				arr[insertIndex] = insertValue;
			}
		}
	}
}

代码写完,小弟能力有限,欢迎各路大神指点!!!

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值