package class01;
/**
* 插入排序:
* 0位置到0位置上有序,然后0位置到1位置上有序,0位置到2位置上有序...0位置到n-1位置上有序
* (可以定义一个end为每一组的第二个位置,即0,1,2,...,n-1)
* 只需要将新来的数的索引(newNumIndex),所对应的数,
* 和它的前一个位置(newNumIndex-1)所在的数,比较并交换。只要同时满足下边while中的两个条件,就一直交换,并newNumIndex--(类似一个指针)。
* 周而复始,完成排序。
*/
public class Code04_InsertionSort {
public static void main(String[] args) {
int[] arr = {8, 7, 6, 5, 4, 2, 1};
printArr(arr);
// insertSort1(arr);
insertSort2(arr);
printArr(arr);
}
public static void insertSort1(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
int N = arr.length;
for (int end = 1; end < N; end++) {
int newNumIndex = end;//新来的数的索引为newNumIndex
//新来的的数的前一个位置没有越界 && 新来的数的前一个数大于这个新来的数
while (newNumIndex - 1 >= 0 && arr[newNumIndex - 1] > arr[newNumIndex]) {
swap(arr, newNumIndex - 1, newNumIndex);//就交换
//并将指针左移一位。指针(即新来的值的索引),一直指着这个新来的数,每次交换后,它就--。
//直到这个新来的数,来到它该停住的位置,也就是它左边没数了,或者它左边的数不大于它了,就停止。跳出循环。
//然后end++,即又来了一个新数,周而复始。
newNumIndex--;
}
}
}
private static void insertSort2(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
int N = arr.length;
//0到0范围上,就一个数,已经有序了。
//所以end=1,即看0到1范围上,是否有序;0到2范围上是否有序;0到3范围上是否有序...周而复始。
for (int end = 1; end < N; end++) {
/*新数一开始,在end位置。*/
//定义pre为新来的数的前一个数的索引,
//如果pre没有越界 && 并且新来的的数的前一个数大于这个新来的数,就交换,并pre--。周而复始。
for (int pre = end - 1; pre >= 0 && arr[pre] > arr[pre + 1]; pre--) {
swap(arr, pre, pre + 1);
}
//这个for循环也可以得出正确结果,而且和insertSort1(...)更接近。
// for (int newNumIndex = end; newNumIndex - 1 >= 0 && arr[newNumIndex - 1] > arr[newNumIndex]; newNumIndex--) {
// swap(arr, newNumIndex - 1, newNumIndex);
// }
}
}
public static void swap(int[] arr, int i, int j) {
int t = arr[j];
arr[j] = arr[i];
arr[i] = t;
}
public static void printArr(int[] arr) {
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
}