给你一个整数数组 nums,请你将该数组升序排列。
示例 1:
输入:nums = [5,2,3,1]
输出:[1,2,3,5]
示例 2:
输入:nums = [5,1,1,2,0,0]
输出:[0,0,1,1,2,5]
提示:
1 <= nums.length <= 5 * 104
-5 * 104 <= nums[i] <= 5 * 104
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/sort-an-array
1 堆排序:
class Solution {
public:
// 建造大顶堆,父节点的值大于左右子节点, 将最小值下沉到数组末尾
void sink(vector<int>& nums, int start, int end){
while(true) {
int i=2*start+1;
if(i>end) {
break;
}
int tmpMax = nums[i];
int childMaxIndex = i;
// 右子节点存在,并且大于左子节点
if(i+1<=end&&nums[i+1]>nums[i]) {
childMaxIndex = i + 1;
}
// 父节点小于子节点的最大值时,父节点下沉
if(nums[start]<nums[childMaxIndex]) {
swap(nums,start,childMaxIndex);
}
start = childMaxIndex;
}
}
void swap(vector<int>& nums, int i, int j){
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
vector<int> sortArray(vector<int>& nums) {
int len = nums.size();
// 先建造大顶堆
for(int i = (len - 1)/2;i>=0;i--) {
sink(nums,i,len-1);
}
int k = len-1;
while(k>0) {
// 将大顶堆的栈顶元素与最后一位元素交换,并更新最后元素的 index
swap(nums,0,k);
k--;
sink(nums,0,k);
}
return nums;
}
};
2 快速排序
class Solution {
public:
int partition(vector<int>& nums, int low, int high) {
int piovt = low;
while(low<high) {
while(low<high && nums[high]>=nums[piovt]) {
high--;
}
while(low<high && nums[low]<=nums[piovt]) {
low++;
}
if(low>=high) {
break;
}
swap(nums,low,high);
}
// 基准元素归位
swap(nums,piovt,high);
// 返回数组中小于 nums[pivot] 的元素中,位置最靠右的索引
return high;
}
void quickSort(vector<int>& nums,int start, int end) {
if(start>=end) {
return;
}
int piovt = partition(nums,start,end);
quickSort(nums,start,piovt-1);
quickSort(nums,piovt+1,end);
}
void swap(vector<int>& nums, int i, int j) {
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
vector<int> sortArray(vector<int>& nums) {
quickSort(nums,0,nums.size()-1);
return nums;
}
};
3 归并排序
class Solution {
public:
void mergeSort(vector<int>& nums, int left, int right) {
if(left>=right) {
return;
}
int mid = left + (right - left)/2;
mergeSort(nums,left,mid);
mergeSort(nums,mid+1,right);
merge(nums,left,mid,right);
}
// 两个有序数组归并
void merge(vector<int>& nums, int left, int mid, int right) {
// 1. 定义数组,用于存放归并排序的结果
vector<int> tmp_nums;
// 2. 排序,将小的元素先存放如定义的数组中
int i=left; // 第一个待合并数组的第一个下标
int j=mid+1; // 第二个待合并数组的第一个下标
while(i<=mid && j<=right) {
if(nums[i]<nums[j]) {
tmp_nums.push_back(nums[i++]);
} else {
tmp_nums.push_back(nums[j++]);
}
}
// 3. 将剩下未放入定义数组的元素均 copy到定义数组中
while(i<=mid) {
tmp_nums.push_back(nums[i++]);
}
while(j<=right) {
tmp_nums.push_back(nums[j++]);
}
cout<< right-left+1 <<endl;
cout<< tmp_nums.size() <<endl;
// 4. 将排序好的元素 copy 回原数组
for(int i=left;i<=right;i++) {
nums[i] = tmp_nums[i-left]; // 注意,新定义数组的下标是从 i-left 开始的,也就是 0
}
}
vector<int> sortArray(vector<int>& nums) {
mergeSort(nums,0,nums.size()-1);
return nums;
}
};