基本思想
把 n 个待排序的元素看成为一个有序表和一个无序表,开始时有
序表中只包含一个元素,无序表中包含有 n-1 个元素,排序过程中每次从无序表中取出第一个元素,把它的排
序码依次与有序表元素的排序码进行比较,将它插入到有序表中的适当位置,使之成为新的有序表。——尚硅谷
简单来说:将数组分为有序表和无序表,每进行一次排序就从无序表中选择一个元素与有序表中的每一个元素进行比较,然后不断地与有序表中地元素进行位置交换,直到找到合适的插入位置。
动画演示
直接插入排序示例
java代码:
package sort;
import java.util.Random;
import java.util.Scanner;
public class InsertSort {
public static void main(String[] args) {
int num, min, max;//数组个数,最小值,最大值
int direction;
int[] arr;//数组
Scanner scanner = new Scanner(System.in);
System.out.printf("请输入要随机生成数组的个数:");
num = scanner.nextInt();
System.out.printf("请输入要随机生成数组的最小值:");
min = scanner.nextInt();
System.out.printf("请输入要随机生成数组的最大值:");
max = scanner.nextInt();
arr = randomArrays(num,min,max);//生成数组
System.out.printf("生成的数组:");
traversalOutput(arr);
insertSort(arr);
}
/**
* 随机生成数组函数
* @param num 数组个数
* @param min 数组值最小值
* @param max 数组值最大值
* @return
*/
public static int[] randomArrays (int num, int min, int max){
Random rd = new Random();
int[] arr = rd.ints(num, min, max + 1).toArray();
return arr;
}
/**
* 数组遍历输出
* @param arr 数组
*/
public static void traversalOutput (int[] arr){
for (int i : arr) {
System.out.printf("%d ", i);
}
System.out.println("");
}
/**
* 交换
* @param arr 数组
* @param i 第一个元素下标
* @param j 第二个元素下标
*/
public static void exchange (int[] arr, int i, int j){
int temp;
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
/**
* 插入排序
* @param arr 排序数组
*/
public static void insertSort(int[] arr) {
int i,j,temp;
for (i = 1; i < arr.length; i++) {
temp = arr[i];
for (j = i; j > 0 && temp < arr[j-1] ; j--) {
arr[j] = arr[j-1];
System.out.printf("第%d轮循环%d次的数组:", i, i - j + 1);
traversalOutput(arr);
}
//当for循环退出时j就是当前元素要插入的位置
arr[j] = temp;
System.out.printf("第%d轮循环%d次的数组:", i, i - j + 1);
traversalOutput(arr);
System.out.println("");
}
}
}
代码分析
/**
* 插入排序
* @param arr 排序数组
*/
public static void insertSort(int[] arr) {
int i,j,temp;
for (i = 1; i < arr.length; i++) {
temp = arr[i];
for (j = i; j > 0 && temp < arr[j-1] ; j--) {
arr[j] = arr[j-1];
System.out.printf("第%d轮循环%d次的数组:", i, i - j + 1);
traversalOutput(arr);
}
//当for循环退出时j就是当前元素要插入的位置
arr[j] = temp;
System.out.printf("第%d轮循环%d次的数组:", i, i - j + 1);
traversalOutput(arr);
System.out.println("");
}
}
第一层循环确定排序的顺序,第二层循环确定有序表。
将要排序的元素保存在一个额外的变量中,与该元素的上一个位置进行比较。
如果为逆序,将上一个元素的值赋给当前这个元素的位置上(不需要担心当前这个元素会丢失,因为该值已被存储下了,上一个元素会变成有两个),直至找到正序的位置,将该值赋在该位置上。
在程序的打印结果上有具体的过程,仔细看看就能理解。