排序算法之:直接插入排序和希尔排序(java)

排序算法的分类:

  • 内部排序:整个排序过程在内存储器中进行。
  • 外部排序:由于待排序元素数量太大,以至于内存储器无法容纳全部数据,排序需要借助外部存储设备才能完成。

直接插入排序与希尔排序效率:

类别 排序方法 时间复杂度 空间复杂度 排序方式 稳定性
平均时间复杂度 最好情况 最坏情况
插入排序 直接插入排序 O(n^2) O(n) O(n^2)^{^{^{^{^{^{}}}}}}^{^{^{^{^{^{^{^{^{^{^{^{}}}}}}}}}}}}^{} O(1) In-place 稳定
希尔排序 O(n\log n) O(n\log^2n) O(n\log^2n) O(1) In-place 不稳定

接口:

package com.my.sort;

public interface IArraySort {
	public int[] sort(int[] sourceArray);
}

1. 直接插入排序

1.1 算法步骤

  • 将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。
  • 从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。)

1.2 代码

package com.my.sort;

import java.util.Arrays;

public class Client {
	public static void main(String[] args) {
		int[] sourceArray = {7,2,6,5,9,4};
		InsertSort iSort = new InsertSort();
		System.out.println(Arrays.toString(sourceArray));
		int[] arr = iSort.sort(sourceArray);
		System.out.println(Arrays.toString(arr));
	}
}
package com.my.sort;

import java.util.Arrays;

public class InsertSort implements IArraySort {

	@Override
	public int[] sort(int[] sourceArray) {
		//对arr进行拷贝,不改变参数内容
		int[] arr = Arrays.copyOf(sourceArray,sourceArray.length);
		//从下标为1的元素开始选择合适的位置插入,因为下标为0的只有一个元素,默认是有序的
		for(int i = 1; i < arr.length; i++) {
			//记录要插入的元素
			int temp = arr[i];
			//记录要插入元素的下标
			int j = i;
			//将要插入元素从后向前与已排序的序列的元素进行比较,若已排序元素大于要插入元素,则向后移动一位,最终找到要插入的位置的下标j
			while(j > 0 && temp < arr[j - 1]) {
				arr[j] = arr[j - 1];
				j--;
			}
			//如果要插入位置的下标不等于要插入元素的原始下标,则插入要插入的元素
			if(j != i) {
				arr[j] = temp;
			}
		}
		return arr;
	}
}

1.3 执行结果

[7, 2, 6, 5, 9, 4]
[2, 4, 5, 6, 7, 9]

2. 希尔排序

2.1 算法步骤

  • 选择一个增量序列 t1,t2,……,tk,其中 ti > tj, tk = 1;
  • 按增量序列个数 k,对序列进行 k 趟排序;
  • 每趟排序,根据对应的增量 ti,将待排序列分割成若干长度为 m 的子序列,分别对各子表进行直接插入排序。仅增量因子为 1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。

2.2 举例说明


要排序数组:int[] arr = {7, 2, 6, 5, 9, 4};

已排序后的数组为:[2, 4, 5, 6, 7, 9]


2.3 代码

package com.my.sort;

import java.util.Arrays;

public class Client {
	public static void main(String[] args) {
		int[] sourceArray = {7,2,6,5,9,4};
		ShellSort sSort = new ShellSort();
		System.out.println(Arrays.toString(sourceArray));
		int[] arr = sSort.sort(sourceArray);
		System.out.println(Arrays.toString(arr));
	}
}
package com.my.sort;

import java.util.Arrays;

public class ShellSort implements IArraySort {

	@Override
	public int[] sort(int[] sourceArray) {
		//对arr进行拷贝,不改变参数内容
		int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
		//设置最开始的增量(间隔gap)为1
		int gap = 1;
		while(gap < arr.length) {
			gap = gap * 2 + 1;
		}
		while(gap > 0) {
			//将待排序列按照增量进行分组
			gap = (int)Math.floor(gap / 2);
			for(int i = gap; i < arr.length; i++) {
				//用tmp记录将要排序的元素
				int tmp = arr[i];
				//用j来记录与将要排序的元素进行比较的元素
				int j = i - gap;
				while(j >= 0 && arr[j] > tmp) {
					//将j交换到将要排序的元素的位置
					arr[j + gap] = arr[j];
					j-=gap;
				}
				//将要排序的元素放到它应该在的位置
				arr[j + gap] = tmp;
			}
		}
		return arr;
	}
}

2.4 执行结果

[7, 2, 6, 5, 9, 4]
[2, 4, 5, 6, 7, 9]

 

猜你喜欢

转载自blog.csdn.net/xiongmengyao/article/details/86742011