归并排序 + 快排 +二分法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012292754/article/details/88431377
原地 稳定 最好 最坏 平均
归并 O(N logN) O(N logN) O(N logN)
快排 O(N logN) O(N^2) O(N logN)

1 归并排序(Merge sort)

package sort;

import java.util.Arrays;

public class MergeSort {

    public static void mergeSort(int[] nums, int numsLength) {
        mergeSortInternally(nums, 0, numsLength - 1);
    }

    private static void mergeSortInternally(int[] nums, int numsStart, int numsEnd) {

        if (numsStart >= numsEnd) {
            return;
        }

        int mid = numsStart + (numsEnd - numsStart) / 2;

        mergeSortInternally(nums, numsStart, mid);
        mergeSortInternally(nums, mid + 1, numsEnd);
        merge(nums, numsStart, numsEnd, mid);
    }

    private static void merge(int[] nums, int numsStart, int numsEnd, int mid) {

        int preIndex = numsStart;
        int backIndex = mid + 1;
        int tmpIndex = 0;

        int[] tmp = new int[numsEnd - numsStart + 1];

        while (preIndex <= mid && backIndex <= numsEnd) {
            if (nums[preIndex] <= nums[backIndex]) {
                tmp[tmpIndex++] = nums[preIndex++];
            } else {
                tmp[tmpIndex++] = nums[backIndex++];
            }
        }

        int remainStart = preIndex;
        int remianEnd = mid;
        if (backIndex <= numsEnd) {
            remainStart = backIndex;
            remianEnd = numsEnd;
        }

        while (remainStart <= remianEnd) {
            tmp[tmpIndex++] = nums[remainStart++];
        }

        // 将tmp 拷贝回 nums[numsStart,...,numsEnd]
        for (int j = 0; j < tmpIndex; j++) {
            nums[numsStart + j] = tmp[j];
        }


    }

    public static void main(String[] args) {
        int[] nums = {9, 8, 7, 6, 5, 4, 3, 2, 1};
        mergeSort(nums, nums.length);
        System.out.println(Arrays.toString(nums));
    }


}

2 快排

package sort;

import java.util.Arrays;

public class QuickSort {

    public static void quickSort(int[] nums, int numsLength) {
        quickSortInternally(nums, 0, numsLength - 1);
    }

    private static void quickSortInternally(int[] nums, int numsStart, int numsEnd) {

        if (numsStart >= numsEnd) {
            return;
        }

        int segIndex = partition(nums, numsStart, numsEnd);
        quickSortInternally(nums, numsStart, segIndex - 1);
        quickSortInternally(nums, segIndex + 1, numsEnd);

    }

    /**
    *   i 把 nums[numsStart,...,numsEnd-1] 分成两部分;
     *   nums[numsStart,...,i-1] 元素小于 pivot, 称为已处理区间;
     *   nums[i,...,numsEnd-1] 是未处理区间;
     *   每次从 nums[i,..,numsEnd-1] 取一个元素 nums[k] 与 pivot 对比
     *   小于pivot,则将其加入已处理区间尾部,也就是 A[i] 的位置
    * */

    private static int partition(int[] nums, int numsStart, int numsEnd) {

        int pivot = nums[numsEnd];


        int i = numsStart;
        for (int k = numsStart; k < numsEnd; ++k) {
            if (nums[k] < pivot) {
                if (i == k) {
                    ++i;
                }else{
                    int tmp = nums[i];
                    nums[i++] = nums[k];
                    nums[k] = tmp;
                }
            }
        }

        int tmp = nums[i];
        nums[i] = nums[numsEnd];
        nums[numsEnd] = tmp;

        return i;
    }

    public static void main(String[] args) {
        int[] nums = {3, 2, 1, 4, 9, 7, 6};
        quickSort(nums, nums.length);
        System.out.println(Arrays.toString(nums));
    }

}

3 二分法 O(log N)

3.1 二分法注意

  • 循环退出条件:low <= high
  • mid 的取值;
  • low 和 high 的更新,

3.2 二分法的局限性

  • 依赖顺序表结构,就是数组;
  • 针对的是有序的数组
package sort;

public class Bsearch {

    public static int bsearch(int[] nums, int len, int val) {
        int low = 0;
        int high = len - 1;

        while (low <= high) {
            int mid = low + (high - low) / 2;
            if (nums[mid] == val) {
                return mid;
            } else if (nums[mid] < val) {
                low = mid + 1;
            } else {
                high = mid - 1;
            }
        }

        return -1;
    }

    // 递归实现
    public static int bsearch_2(int[] nums, int len, int val) {
        return bsearchInternally(nums, 0, len - 1, val);
    }

    private static int bsearchInternally(int[] nums, int low, int high, int val) {
        if (low > high) {
            return -1;
        }
        int mid = low + (high - low) / 2;

        if (nums[mid] == val) {
            return mid;
        } else if (nums[mid] < val) {
            return bsearchInternally(nums, mid + 1, high, val);
        } else {
            return bsearchInternally(nums, low, mid - 1, val);
        }

    }

    public static void main(String[] args) {
        int[] nums = {6, 5, 4, 3, 2};

        int index = bsearch(nums, nums.length, 4);

        System.out.println(index);
    }


}

猜你喜欢

转载自blog.csdn.net/u012292754/article/details/88431377
今日推荐