Skip to content

排序算法

常见排序算法

冒泡排序

java
public void 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;
            }
        }
    }
}
// 时间复杂度:O(n²)
// 空间复杂度:O(1)
// 稳定性:稳定

快速排序

java
public void quickSort(int[] arr, int left, int right) {
    if (left < right) {
        int pivot = partition(arr, left, right);
        quickSort(arr, left, pivot - 1);
        quickSort(arr, pivot + 1, right);
    }
}

private int partition(int[] arr, int left, int right) {
    int pivot = arr[right];
    int i = left - 1;

    for (int j = left; j < right; j++) {
        if (arr[j] < pivot) {
            i++;
            swap(arr, i, j);
        }
    }
    swap(arr, i + 1, right);
    return i + 1;
}
// 时间复杂度:O(n log n)
// 空间复杂度:O(log n)
// 稳定性:不稳定

归并排序

java
public void mergeSort(int[] arr, int left, int right) {
    if (left < right) {
        int mid = left + (right - left) / 2;
        mergeSort(arr, left, mid);
        mergeSort(arr, mid + 1, right);
        merge(arr, left, mid, right);
    }
}

private void merge(int[] arr, int left, int mid, int right) {
    int[] temp = new int[right - left + 1];
    int i = left, j = mid + 1, k = 0;

    while (i <= mid && j <= right) {
        temp[k++] = arr[i] < arr[j] ? arr[i++] : arr[j++];
    }

    while (i <= mid) temp[k++] = arr[i++];
    while (j <= right) temp[k++] = arr[j++];

    System.arraycopy(temp, 0, arr, left, temp.length);
}
// 时间复杂度:O(n log n)
// 空间复杂度:O(n)
// 稳定性:稳定

堆排序

java
public void heapSort(int[] arr) {
    // 建堆
    for (int i = arr.length / 2 - 1; i >= 0; i--) {
        heapify(arr, arr.length, i);
    }

    // 排序
    for (int i = arr.length - 1; i > 0; i--) {
        swap(arr, 0, i);
        heapify(arr, i, 0);
    }
}

private void heapify(int[] arr, int n, int i) {
    int largest = i;
    int left = 2 * i + 1;
    int right = 2 * i + 2;

    if (left < n && arr[left] > arr[largest]) {
        largest = left;
    }
    if (right < n && arr[right] > arr[largest]) {
        largest = right;
    }

    if (largest != i) {
        swap(arr, i, largest);
        heapify(arr, n, largest);
    }
}
// 时间复杂度:O(n log n)
// 空间复杂度:O(1)
// 稳定性:不稳定

LeetCode题目

排序数组(LeetCode 912)

java
public int[] sortArray(int[] nums) {
    quickSort(nums, 0, nums.length - 1);
    return nums;
}

颜色分类(LeetCode 75)

java
public void sortColors(int[] nums) {
    int left = 0, right = nums.length - 1, i = 0;

    while (i <= right) {
        if (nums[i] == 0) {
            swap(nums, i++, left++);
        } else if (nums[i] == 2) {
            swap(nums, i, right--);
        } else {
            i++;
        }
    }
}

练习题

  1. 合并区间(LeetCode 56)
  2. 最大间距(LeetCode 164)
  3. 数组中的第K个最大元素(LeetCode 215)

Released under the MIT License.