文章目录
一、常用的排序算法
1.1、快速排序
快速排序是一种不稳定的排序算法。首先设置三个指针,first
指向区间左端,last
指向区间右端,key
为当前的分界值。从待排序的数据元素中选取一个(通常为第一个)作为基准值元素 key
,设置双指针 first
指向区间左端,last
指向区间右端。
- 首先用
num[last]
与key
进行比较,如果num[last] >= key
,则移动右指针last--
;直到当num[last] < key
时,则将num[first] = num[last]
。 - 查找上述条件并完成交换后,转向左边部分,用
num[first]
与key
进行比较,如果num[first] <= key
, 则first++
,然后继续进行比较,直至num[first] > key
,则将num[last] = num[first]
。 - 重复上述一二步骤。
class Solution {
public void quick_sort(int[] nums, int l, int r) {
if (l + 1 >= r) {
return;
}
int first = l, last = r - 1, key = nums[first];
while (first < last) {
while (first < last && nums[last] >= key) {
last--;
}
nums[first] = nums[last];
while (first < last && nums[first] <= key) {
first++;
}
nums[last] = nums[first];
}
nums[first] = key;
quick_sort(nums, l, first);
quick_sort(nums, first + 1, r);
}
}
复杂度分析
- 时间复杂度:平均时间复杂度为 O(nlogn),其中 n 是数组 nums 的长度。在最坏的情况下,待排序的数组时正序或倒序,比较次数为
n + (n-1) + (n-2) + (n-3) + … +1 = n*(n + 1)/2
,因此时间复杂度为O(n2)。 - 空间复杂度:O(logn)。快速排序使用的空间是O(1)的,也就是常数级,而真正消耗空间的就是递归调用。在最坏的情况下,空间复杂度是O(n)。
1.2、归并排序
归并排序是一种稳定的排序算法。当我们要排序这样一个数组的时候,首先将这个数组从中间分成两个子数组,一直递归地把子数组划分成更小的子数组,直到子数组里面只有一个元素。接下来依次按照递归的返回顺序,不断地合并排好序的子数组,直到最后把整个数组的顺序排好。
class Solution {
public void mergeSort(int[] nums, int l, int r, int[] temp) {
if (l + 1 >= r) {
return;
}
int m = l + (r - l) / 2;
mergeSort(nums, l, m, temp);
mergeSort(nums, m, r, temp);
int p = l, q = m, i = l;
while (p < m || q < r) {
if (q >= r || (p < m && nums[p] <= nums[q])) {
temp[i++] = nums[p++];
} else {
temp[i++] = nums[q++];
}
}
System.arraycopy(temp, l, nums, l, r - l);
}
}
复杂度分析
- 时间复杂度:O(nlogn),其中 n 是数组 num