二分查找和排序算法

194 阅读1分钟

二分查找

要求是顺序数组

public static int binarySearch(int[] arr, int a) {
    int high = arr.length - 1;
    int low = 0;
    int mid;
    while(high > low) {
        mid = (low + high) / 2 + low;
        if(arr[mid] == a) return mid;
        else if (arr[mid] > a) low = mid + 1;
        else high = mid - 1;
    }
    return -1;
}

冒泡排序

public static int[] bubbleSort(int[] arr) {
    for(int i = 0; i < arr.length - 1; i++) {
        for(int j = 0; j < arr.length - 1 -i; j++) {
            if(arr[j] > arr[j + 1]) {
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
    return arr;
}

插入排序

public static int[] insertSort(int[] arr){
    for(int i = 0; i < arr.length; i++) {
        int insertVal = arr[i];
        int j;
        while(j >= 0;arr[j] < insertVal) {
            arr[j + 1] = arr[j];
            j--;
        }
        arr[j + 1] = insertVal;
    }
    return arr;
}

希尔排序

插入排序的变形,分组版插入排序

public static int[] shellSort(int[] arr) {
    int dk = arr.length / 3 + 1;
    while(dk > 1){
        shellInsertSort(arr, dk);
        dk = dk / 3 + 1;
    }
    if(dk == 1) shellInsertSort(arr, dk);
    return arr;
}
public static void shellInsertSort(int[] arr, int dk) {
    for(int i = dk; i < arr.length; i++) {
        int insertVal = arr[i];
        int j;
        for(j = i - dk; j >= 0 && arr[j] > insertVal;j -= dk) {
            arr[j + dk] = arr[j];
        }
        arr[j + dk] = insertVal;
    }
}

快速排序

public static int[] quickSort(int[] arr, int low, int high) {
    int start = low;
    int end = high;
    int key = arr[low];
    while(end > start) {
        while(end > start && arr[end] >= key) {
            end--;
        }
        if(arr[end] < key){
            int temp = arr[end];
            arr[end] = arr[start];
            arr[start] = temp;
        }
        while(end > start && arr[start] <= key) {
            start++;
        }
        if(arr[start] > key) {
            int temp = arr[start];
            arr[start] = arr[end];
            arr[end] = temp;
        }
    }
    if(start > low) quickSort(arr, low, start - 1);
    if(end < high) quickSort(arr, end + 1, high);
    return arr;
}

归并排序

public static int[] mergeSort(int[] arr) {
    sort(arr, 0, arr.length - 1);
    return arr;
}
public static void sort(int[] arr, int low, int high) {
    if(low >= high) return;
    int center = (low + high) / 2;
    sort(arr, low, center);
    sort(arr, center + 1, high);
    merge(arr, low, center, high); 
}
public static void merge(int[] arr, int low, int center, int high) {
    int[] temArr = new int[arr.length];
    int index1 = low;
    int index2 = low;
    int mid = center + 1;
    while(low <= center && high >= mid) {
        if(arr[low] > arr[mid]) temArr[index1++] = arr[mid++];
        else temArr[index1++] = arr[low++];
    }
    while(low <= center) {
        temArr[index1++] = arr[low++];
    }
    while(mid <= high) {
        temArr[index1++] = arr[mid++];
    }
    while(index2 <= high) {
        arr[index2] = temArr[index2++];
    }
}

桶排序

利用ArrayList以及Collections.sort(),可以复习泛型类相关知识点。

public static int[] bucketSort(int[] arr) {
    int min = Integer.MAX_VALUE;
    int max = Integer.MIN_VALUE;
    for(int i = 0; i < arr.length; i++) {
        max = Math.max(max, arr[i]);
        min = Math.min(min, arr[i]);
    }
    int bucketNum = (max - min) / arr.length + 1;
    ArrayList<ArrayList<Integer>> bucketArr = new ArrayList<>(bucketNum);
    for(int i = 0; i < bucketNum; i++) {
        bucketArr.add(new ArrayList<Integer>() );
    }
    for(int i = 0; i < arr.length; i++) {
        int num = (arr[i] - min) /(arr.length);
        bucketArr.get(num).add(arr[i]);
    }
    for(int i = 0; i <= bucketArr.size(); i++) {
        Collections.sort(bucketArr.get(i));
    }
    ArrayList<Integer> resultList = new ArrayList<>();
    for(int i = 0; i <= bucketNum; i++) {
        resultList.addAll(bucketArr.get(i));
    }
    for(int i = 0; i <= arr.length - 1; i++) {
        arr[i] = resultList.get(i);
    }
    return arr;
}

基数排序

桶排序变形,按位切割

private static int[] radixSort(int[] arr, int maxDigit) {
    double max = Math.pow(10, maxDigit + 1);
    int n = 1;
    int k = 0;
    int length = arr.length;
    int[][] bucket = new int[10][length];
    int[] order = new int[length];
    while(n < max) {
        for(int num : arr) {
            int digit = (num / n) % 10;
            bucket[digit][order[digit]] = num;
            order[digit]++;
        }
        for(int i = 0; i < length; i++) {
            if(order[i] != 0){
                for(int j = 0; j < order[i]; j++){
                    arr[k] = bucker[i][j];
                    k++;
                }
            }
            order[i] = 0;
        }
        n *= 10;
        k = 0;
    }
    return arr;
}