快排、归并和堆排
原题:https://leetcode-cn.com/problems/sort-an-array/
快排主要是先找一个随机数l作为换的标杆,比他大的放后面,比他小的放前面,为了方便找到位置,将它交换到区间最前面。然后从右边找到比它小的j,左边找到比它的大的i(先找j后i,否则当nums[left]最小时,i会一直找到最后一个right,但是nums[right]仍然小于nums[left],但是按照我们的代码就会将他们交换,但是反过来先找j不会,因为出现类似的情况j会到达left的位置,而交换left和left是不会有影响的)交换它们直到i和j碰到,然后将该值与left交换(因为当i==j时,i和前面都是小于或者就是nums[left]的,后面都是大于的)。
class Solution { public: void quick_sort(vector<int>& nums, int left, int right){ if(left >= right) return; int l = rand() % (right - left + 1) + left; swap(nums[left], nums[l]); int i = left, j = right; while(i < j){ while(i < j && nums[j] >= nums[left]) j--; while(i < j && nums[i] <= nums[left]) i++; swap(nums[i], nums[j]); } swap(nums[left], nums[i]); // for(auto item: nums) // cout << item << " "; // cout << i << endl; quick_sort(nums, left, i - 1); quick_sort(nums, i + 1, right); } void merge_sort(vector<int>& nums, int left, int right){ if(left >= right) return; int mid = (left + right) / 2, i = left, j = mid + 1, cnt = 0; merge_sort(nums, left, mid); merge_sort(nums, mid + 1, right); vector<int> v; while(i <= mid && j <= right){ if(nums[i] < nums[j]) v.push_back(nums[i++]); else v.push_back(nums[j++]); } while(i <= mid) v.push_back(nums[i++]); while(j <= right) v.push_back(nums[j++]); for(int k = left; k <= right; k++){ nums[k] = v[k - left]; } } void downJust(vector<int>& nums, int x){ int i = 1, j = 2; while(j <= x){ if(j + 1 <= x && nums[j] > nums[j - 1]) j++; if(nums[i - 1] < nums[j - 1]) { swap(nums[i - 1], nums[j - 1]); i = j; j *= 2; } else break; } } void upJust(vector<int>& nums, int x){ int i = x + 1, j = (x + 1) / 2; while(j){ if(nums[i - 1] > nums[j - 1]) { swap(nums[i - 1], nums[j - 1]); i = j; j /= 2; } else break; } } void heap_sort(vector<int>& nums, int left, int right){ for(int i = 0; i < nums.size(); i++){ upJust(nums, i); } for(int i = nums.size() - 1; i > 0; i--){ swap(nums.front(), nums[i]); downJust(nums, i); } } vector<int> sortArray(vector<int>& nums) { quick_sort(nums, 0, nums.size() - 1); // heap_sort(nums, 0, nums.size() - 1); return nums; } };