快排
- 快速排序的最优情况是每一次取到的元素都刚好平分整个数组,T(n) = 2 * T(n/2) + O(n),由 master 公式得到算法的时间复杂度为 O(nlogn),空间复杂度为 O(logn)
- 最坏情况是数组本身有序,每一次取到的元素都是待排序列中的最值,效果相当于冒泡排序。这种情况下,算法的时间复杂度是 O(n^2),空间复杂度为 O(n)
经典快排
- 确定性的快排在选取主元的时候,每次都选取最左边的元素。当序列为有序时,会发现划分出来的两个子序列一个里面没有元素,而另一个则只比原来少一个元素。为了避免这种情况,引入随机化来破坏这种有序状态。
| #include <vector> |
| |
| using namespace std; |
| |
| class Solution { |
| public: |
| void quickSort(vector<int> &array, int left, int right) { |
| if (left >= right) return; |
| int i = left; |
| int j = right; |
| int pivot = array[left]; |
| |
| while (i < j) { |
| while (i < j && pivot <= array[j]) { |
| j--; |
| } |
| if (i < j) { |
| array[i] = array[j]; |
| i++; |
| } |
| while (i < j && pivot >= array[i]) { |
| i++; |
| } |
| if (i < j) { |
| array[j] = array[i]; |
| j--; |
| } |
| } |
| array[i] = pivot; |
| quickSort(array, left, i - 1); |
| quickSort(array, i + 1, right); |
| } |
| |
| vector<int> sortArray(vector<int> &nums) { |
| quickSort(nums, 0, nums.size() - 1); |
| return nums; |
| } |
| }; |
随机快排
- 在随机化的快排里面,随机选取待排序列中的一个元素作为主元,然后再进行划分,就可以降低选到最值的概率。
| #include <vector> |
| #include <cstdlib> |
| #include <ctime> |
| |
| using namespace std; |
| |
| class Solution { |
| public: |
| void quickSort(vector<int> &nums, int left, int right) { |
| if (left >= right) return; |
| int i = left; |
| int j = right; |
| |
| |
| srand(time(nullptr)); |
| int pick = left + (rand() % (right - left + 1)); |
| swap(nums[left], nums[pick]); |
| int pivot = nums[left]; |
| |
| while (i < j) { |
| while (i < j && nums[j] >= pivot) j--; |
| if (i < j) nums[i++] = nums[j]; |
| while (i < j && nums[i] <= pivot) i++; |
| if (i < j) nums[j--] = nums[i]; |
| } |
| nums[i] = pivot; |
| quickSort(nums, left, i - 1); |
| quickSort(nums, i + 1, right); |
| } |
| |
| vector<int> sortArray(vector<int> &nums) { |
| quickSort(nums, 0, nums.size() - 1); |
| return nums; |
| } |
| }; |
荷兰国旗问题
- 也是由大佬 Edsger Dijkstra 提出的
| #include <vector> |
| #include <cstdlib> |
| #include <ctime> |
| |
| using namespace std; |
| |
| class Solution { |
| public: |
| void sortColors(vector<int> &nums) { |
| |
| int l = 0; |
| |
| int r = nums.size() - 1; |
| int index = l; |
| while (index <= r) { |
| if (nums[index] == 1) { |
| index++; |
| } else if (nums[index] == 2) { |
| swap(nums[index], nums[r--]); |
| } else if (nums[index] == 0) { |
| swap(nums[index++], nums[l++]); |
| } |
| } |
| } |
| }; |
荷兰国旗版快排
- 原版的快排只能以 pivot 为中心,小于等于 pivot 的在左侧,大于在右侧,之确保左侧最后一个是 pivot。处理过程是从两侧向中间。
- 荷兰国旗版快排,可以将所有等于 pivot 的放到一起,处理过程是从左到右。
| #include <vector> |
| #include <cstdlib> |
| #include <ctime> |
| |
| using namespace std; |
| |
| class Solution { |
| public: |
| |
| void quickSort(vector<int> &nums, int left, int right) { |
| if (left >= right) return; |
| |
| |
| srand(time(nullptr)); |
| int pick = left + (rand() % (right - left + 1)); |
| swap(nums[left], nums[pick]); |
| int pivot = nums[left]; |
| |
| |
| int l = left; |
| |
| int r = right; |
| |
| int index = l; |
| while (index <= r) { |
| if (nums[index] == pivot) { |
| index++; |
| } else if (nums[index] < pivot) { |
| swap(nums[index++], nums[l++]); |
| } else if (nums[index] > pivot) { |
| swap(nums[index], nums[r--]); |
| } |
| } |
| |
| quickSort(nums, left, l - 1); |
| quickSort(nums, r + 1, right); |
| } |
| |
| vector<int> sortArray(vector<int> &nums) { |
| quickSort(nums, 0, nums.size() - 1); |
| return nums; |
| } |
| }; |
本文作者:n1ce2cv
本文链接:https://www.cnblogs.com/sprinining/p/18433037
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步