T02_插入排序3种实现


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);
    }


}
posted @ 2020-11-30 21:30  linglongfang  阅读(96)  评论(0)    收藏  举报