赞
踩
排序算法稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排序算法是稳定的;否则称为不稳定的。
归并排序稳不稳定关键在于merge函数。在合并过程中,如果A[p..q]和A[q+1...r]之间有值相同元素,先把A[p...q]中的元素放入tmp数组。这样就保证了值相同的元素,在合并的先后顺序不变
归并处理过程由下到上,先处理子问题,在合并
递归代码的时间复杂度可以写成递推公式。
(1)假设对n个元素规定需要的时间是T(n),分解成两个子数组排序的时间T(n/2)
(2)merge函数时间复杂度O(n)
归并排序的时间复杂度计算公式:
T(1) = C; n = 1,只需要常量级的执行时间C
T(n)=2*T(n/2) + n; n > 1
进一步分解得出结论,得出结论T(n)=2^kT(n/2^k) +kn,当T(n/2^k)=T(1)时,就是n/2^k得到k=log2(n),带入公式得到,T(n)=Cn+nlog2n
时间复杂度稳定,最好最坏,平均都是O(nlogn)
在任意时刻,CPU只会有一个函数在执行,只会有一个临时的内存在使用。临时内存空间最大不会超过n个数据大小
(1)不是原地排序算法,merge函数需要借助额外存储空间
先局部有序,然后在整体有序
代码:快速排序代码实现_INGNIGHT的博客-CSDN博客
比如数组:6,5,6,3,4,经过第一次分区之后,两个6的顺序会有改变。(选取下表最高的值4为pivot)
快排处理过程由上到下,先分区,在处理子问题。原地排序,解决归并排序占用过多内存问题。
(1)每次分区操作,选择的pivot都很合适,正好能将大区间对等一分为二。原数据已经有序,1,3,5,6,8,每次选取最后一个元素作为pivot,每次分区得到的两个区间都是不均等的,需要进行大约n次分区操作。每次分区平均扫面大约n/2个元素,这是快排时间复杂度退化为O(n^2)
先整体有序,在局部有序
题目:
https://blog.csdn.net/INGNIGHT/article/details/131625238
12 | 排序(下):如何用快排思想在O(n)内查找第K大元素?归并排序和快速排序-CSDN博客
algo/c-cpp/12_sorts/quick_sort.c at master · wangzheng0822/algo · GitHub
- class Solution {
- public:
- vector<int> sortArray(vector<int>& nums) {
- if (nums.size() <= 0) {
- return nums;
- }
- quick_sort(nums, 0, nums.size()-1);
- return nums;
- }
- private:
- void quick_sort(std::vector<int>& nums, int left, int right) {
- if (left >= right) {
- return;
- }
- int mid = partition(nums, left, right);
- // mid然后的右边区间起始点
- quick_sort(nums, left, mid-1);
- quick_sort(nums, mid, right);
- }
- int partition(std::vector<int>& nums, int left, int right) {
-
- int index = random() %(right-left+1);
- swap(nums[left], nums[left+index]);
- int val = nums[left];
- // 和val相等的元素均匀的分布在左右两边
- while (left <= right) {
- while (left <= right && nums[left] < val ) {
- ++left;
- }
- while (left <= right && nums[right] > val) {
- --right;
- }
- // 两个和val相等的元素也会进行交换
- if (left <= right) {
- swap(nums[left], nums[right]);
- ++left;
- --right;
- }
- }
- // 此时left一定是在right的右边
- return left;
- }
- };
- class Solution {
- public:
- vector<int> sortArray(vector<int>& nums) {
- if (nums.size() <= 0) {
- return nums;
- }
- quick_sort(nums, 0, nums.size()-1);
- return nums;
- }
- private:
- void quick_sort(std::vector<int>& nums, int left, int right) {
- if (left >= right) {
- return;
- }
- std::pair<int, int> mid = partition(nums, left, right);
- // mid然后的右边区间起始点
- quick_sort(nums, left, mid.second);
- quick_sort(nums, mid.first, right);
- }
- std::pair<int, int> partition(std::vector<int>& nums, int left, int right) {
-
- int index = random() %(right-left+1);
- swap(nums[left], nums[left+index]);
- int val = nums[left];
- // 和val相等的元素均匀的分布在左右两边
- while (left <= right) {
- while (left <= right && nums[left] < val ) {
- ++left;
- }
- while (left <= right && nums[right] > val) {
- --right;
- }
- // 两个和val相等的元素也会进行交换
- if (left <= right) {
- swap(nums[left], nums[right]);
- ++left;
- --right;
- }
- }
- // 此时left一定是在right的右边
- return std::pair<int, int>(left, right);
- }
- };
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。