import java.util.Arrays;
import java.util.Objects;
import static cn.linglongfang.algorithm.sort.T00_Utils.*;
/**
* 插入排序
* 遍历数组,使得前半部分是一直有序的。
* 0 ~ 1位置有序
* 0 ~ 2位置有序
* 0 ~ 3位置有序
* 0 ~ 4位置有序
* @author Linglong Fang
*/
public class T02_InsertionSort {
public static void main(String[] args) {
final int maxSize = 100;
final int maxValue = 100;
final int NUM = 50_0000;
boolean success = true;
for (int i = 0; i < NUM; i++) {
int[] arr = generateRandomArray(maxSize, maxValue);
int[] arr1 = copyArray(arr);
int[] arr2 = copyArray(arr);
int[] arr3 = copyArray(arr);
int[] arr4 = copyArray(arr);
insertionSort1(arr1);
insertionSort2(arr2);
insertionSort3(arr3);
Arrays.sort(arr4);
if (!isEquals(arr1, arr4) || !isEquals(arr2, arr4) || !isEquals(arr3, arr4)) {
System.out.println(Arrays.toString(arr));
System.out.println(Arrays.toString(arr1));
System.out.println(Arrays.toString(arr2));
System.out.println(Arrays.toString(arr3));
System.out.println(Arrays.toString(arr4));
success = false;
break;
}
}
if (success) {
System.out.println("你可真是个小机灵鬼");
} else {
System.out.println("你可真是个小笨蛋");
}
}
//交换插入 ,一次一次往前交换
public static void insertionSort1(int[] arr){
if (Objects.isNull(arr) || arr.length < 2 ){
return;
}
for (int i = 1; i < arr.length ; i++) {
for (int j = i-1 ; j >= 0 ; j--) {
if ( arr[j+1] >= arr[j]){
break;
}else{
sweep(arr,j+1,j);
}
}
}
}
//顺序移动,找到位置再插入
public static void insertionSort2(int[] arr){
if (Objects.isNull(arr) || arr.length < 2 ){
return;
}
for (int i = 1; i < arr.length ; i++) {
int temp = arr[i];
for (int j = i-1 ; j >= 0 ; j--) {
if ( temp >= arr[j]){
arr[j+1] = temp;
break;
}else{
arr[j+1] = arr[j];
if (j == 0 ){
arr[0] = temp;
}
}
}
}
}
//借助二分法,快速定位到位置
public static void insertionSort3(int[] arr){
if (Objects.isNull(arr) || arr.length < 2 ){
return;
}
for (int i = 1; i < arr.length ; i++) {
int temp = arr[i];
int k = indexOf(arr, 0, i-1, temp);
for (int j = i-1; j >= k; j--) {
arr[j+1] = arr[j];
}
arr[k] = temp;
}
}
//找到大于等于目标数值的最左位置
private static int indexOf(int[] arr , int low , int high, int target){
while (low <= high){
int mid = low + ((high-low)>>1);
if (arr[mid] == target){
return mid;
}else if(arr[mid] > target){
high = mid-1 ;
}else{
low = mid+1;
}
}
return low;
}
/**
* 对比几种插入排序算法的快慢
*/
public static void timeCompare(){
int num = 100;
int maxSize = 3_0000;
int maxValue = 10_0000_000;
int x = 0 ;
int y = 0 ;
int z = 0 ;
int w = 0 ;
for (int i = 0; i < num; i++) {
int[] arr = generateRandomArray(maxSize, maxValue);
int[] arr1 = copyArray(arr);
int[] arr2 = copyArray(arr);
int[] arr3 = copyArray(arr);
int[] arr4 = copyArray(arr);
long point1 = System.currentTimeMillis();
insertionSort1(arr1);
long point2 = System.currentTimeMillis();
insertionSort2(arr2);
long point3 = System.currentTimeMillis();
insertionSort3(arr3);
long point4 = System.currentTimeMillis();
Arrays.sort(arr4);
long point5 = System.currentTimeMillis();
x += point2 - point1;
y += point3 - point2;
z += point4 - point3;
w += point5 - point4;
}
System.out.println(x);
System.out.println(y);
System.out.println(z);
System.out.println(w);
System.exit(0);
}
}