十大经典排序算法之插入排序(Insertion Sort)

插入排序(Insertion-Sort)的算法描述是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。

通俗点理解就是:每步将一个待排序的记录,按其顺序码大小插入到前面已经排序的字序列的合适位置(从后向前找到合适位置后),直到全部插入排序完为止

1.1 算法描述

一般来说,插入排序都采用in-place在数组上实现。具体算法描述如下:

  • 从第一个元素开始,该元素可以认为已经被排序;
  • 取出下一个元素,在已经排序的元素序列中从后向前扫描;
  • 如果该元素(已排序)大于新元素,将该元素移到下一位置;
  • 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;
  • 将新元素插入到该位置后;
  • 重复步骤2~5。

1.2 动图演示

十大经典排序算法之插入排序(Insertion Sort)_第1张图片

1.3 例题分析

有一数组 int[] arr={3,1,5,4,2};使用插入排序每一趟的结果如下:

---------------------------------------------------------------

第一趟排序: 原始数据:3 1 5 4 2

1比3小,则1和3换位置

排序结果:1 3 5 4 2

---------------------------------------------------------------

第二趟排序: 5比3大,不需要调整

排序结果:1 3 5 4 2

---------------------------------------------------------------

第三趟排序: 4比5小,则4和5 换位置,

此时4比3大,则不再继续调整

排序结果:1 3 4 5 2

---------------------------------------------------------------

第四趟排序: 2比5小,2和5换位置,2又比4小,

2继续和4换位置,2仍然比3小,继续和3换位置,

最后2比1大,不再调整

排序结果:1 2 3 4 5

---------------------------------------------------------------

1.4 代码展示

//定义了一个抽象方法,里面是打印算法排序的通用方法
public abstract class SortBase {
	public abstract int[] sort(int[] a);
	public static void print(String prefix, int[] arrayForSort) {
		System.out.print(prefix + ":");
		System.out.print("[");
		for (int i = 0; i < arrayForSort.length; i++) {
			if (i == arrayForSort.length - 1) {
				System.out.print(arrayForSort[i]);
			} else {
				System.out.print(arrayForSort[i] + " ,");
			}
		}
		System.out.println("]");
	}

}
import java.util.Scanner;

public class insertionSort extends SortBase {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入元素个数:");
		int n = sc.nextInt();
		int arr[] = new int[n];
		System.out.println("请依次输入元素:");
		for (int i = 0; i < arr.length; i++) {
			arr[i] = sc.nextInt();
		}
		insertionSort is = new insertionSort();
		is.sort(arr);

	}

	@Override
	public int[] sort(int[] array) {
		//打印排序前的初始结果
		print("排序前", array);
		if (array.length == 0) {
			return array;
		}
		// 从下标为1开始比较,直到数组的末尾
		for (int i = 1; i < array.length; i++) {
			int j;
			// 将要比较的元素存放到临时变量中
			int temp = array[i];
			// 与前一元素一次比较,如果前一元素比要插入的元素大,则互换位置
			for (j = i - 1; j >= 0 && array[j] > temp; j--) {
				array[j + 1] = array[j];
			}
			// 将比较后的元素插入
			array[j + 1] = temp;
			//打印每一次排序的结果
			print("第" + i + "趟排序", array);
		}
		//打印最终排序的结果
		print("排序后", array);
		return array;
	}

}

1.5 测试案例

十大经典排序算法之插入排序(Insertion Sort)_第2张图片

1.6 小结

插入排序的时间复杂度 就是判断比较次数有多少,而比较次数与 待排数组的初始顺序有关,当待排数组有序时,没有移动操作此时复杂度为O(N),当待排数组是逆序时,比较次数达到最大--对于下标 i 处的元素,需要比较 i-1 次。总的比较次数:1+2+...+N-1 ,故时间复杂度为O(N^2)

你可能感兴趣的:(算法设计与分析)