十大排序算法 - 上

31 阅读2分钟

1. 冒泡排序

  • 时间复杂度:最好O(n),最差O(n^2),平均O(n^2)
  • 空间复杂度:O(1)
  • 是否稳定:是

冒泡排序通过两两交换,将最大的数放到末尾,使末尾形成有序

public void bubbleSort(int[] nums) {
    int n = nums.length;
    for (int i = 1; i < n; i++) {
        boolean flag = true;
        for (int j = 0; j < n - i; j++) {
            if (nums[j] > nums[j + 1]) {
                int temp = nums[j + 1];
                nums[j + 1] = nums[j];
                nums[j] = temp;
                flag = false;
            }
        }
        if (flag) {
            break;
        }
    }
}

2. 快速排序

  • 时间复杂度:最好O(nlogn),最差O(nlogn),平均O(nlogn)
  • 空间复杂度:O(logn)
  • 是否稳定:否

快速排序通过选择一个数,将比这个数小的放到这个数的左边,比这个数大的放到右边,从而确定这个数的位置,递归处理左边和右边的无序子数组

public void quickSort(int[] nums) {
    quickSort0(nums, 0, nums.length - 1);
}

void quickSort0(int[] nums, int left, int right) {
    if (left >= right) {
        return;
    }
    int pivot = nums[right];
    int p = left;
    for (int i = left; i < right; i++) {
        if (nums[i] < pivot) {
            int temp = nums[p];
            nums[p] = nums[i];
            nums[i] = temp;
            p++;
        }
    }
    nums[right] = nums[p];
    nums[p] = pivot;
    quickSort0(nums, left, p - 1);
    quickSort0(nums, p + 1, right);
}

3. 简单插入排序

  • 时间复杂度:最好O(n),最差O(n^2),平均O(n^2)
  • 空间复杂度:O(1)
  • 是否稳定:是

简单插入排序通过不断在数组左边构建有序数组来排序,具体方式是:当前数字从前面的有序数组中的末尾开始寻找子集可以插入的位置

public void simpleInsertSort(int[] nums) {
    int n = nums.length;
    for (int i = 1; i < n; i++) {
        int cur = nums[i], j = i - 1;
        while (j >= 0 && nums[j] > cur) {
            nums[j + 1] = nums[j];
            j--;
        }
        nums[j + 1] = cur;
    }
}

4. 希尔排序

  • 时间复杂度:最好O(nlogn),最差O(n^2),平均O(nlogn)
  • 空间复杂度:O(1)
  • 是否稳定:否

希尔排序和简单插入排序类似,也是通过构建有序数组,新的数字在有序数组插入完成的,不同的是希尔排序需要构建的有序数组是存在间隙的,这个间隙不断减小,最后为1

public void sheelSort(int[] nums) {
    int n = nums.length;
    int gap = n / 2;
    while (gap > 0) {
        for (int i = gap; i < n; i++) {
            int cur = nums[i], j = i - gap;
            while (j >= 0 && nums[j] > cur) {
                nums[j + gap] = nums[j];
                j -= gap;
            }
            nums[j + gap] = cur;
        }
        gap /= 2;
    }
}