详细的十大排序算法(加注释版),此外,还可以多去力扣第912题“排序数组”的题解区看一下。
面试常问的是快速排序、归并排序和堆排序。
快速排序
class Solution {
public:
vector<int> sortArray(vector<int>& nums) {
int length = nums.size();
if(length <= 1)
return nums;
quickSort(nums, 0, length - 1);
return nums;
}
// 加了随机切分元素的快排quickSort(基于partition改造)
void quickSort(vector<int> &nums, int low, int high){
if(low >= high)
return;
// 随机选择区间内的一个元素作为切分元素
swap(nums[low], nums[rand() % (high - low + 1) + low]);
// 常规partition
int temp = nums[low];
int left = low, right = high;
while(left < right){
while(left < right && nums[right] >= temp)
right--;
nums[left] = nums[right];
while(left < right && nums[left] <= temp)
left++;
nums[right] = nums[left];
}
nums[left] = temp;
int mid = left;
quickSort(nums, low, mid - 1);
quickSort(nums, mid + 1, high);
}
};
归并排序
// 总体分为“mergeSort”和“merge”两个部分
class Solution {
public:
vector<int> sortArray(vector<int>& nums) {
int length = nums.size();
if(length <= 1)
return nums;
vector<int> temp(length); // 归并排序需要一个“辅助数组”(注意初始化大小)
mergeSort(nums, 0, length - 1, temp);
return nums;
}
// 归并排序
void mergeSort(vector<int> &nums, int low, int high, vector<int> &temp){
if(low >= high)
return;
// 类似于 逐步二分地归并
int mid = low + ((high - low) >> 1); // (low + high) >> 1 这样可能溢出
mergeSort(nums, low, mid, temp);
mergeSort(nums, mid + 1, high, temp);
merge(nums, temp, low, mid, high);
}
// 相邻两个有序子序列的归并(此时的nums为两段部分有序的数组)
void merge(vector<int> &nums, vector<int> &temp, int low, int mid, int high){
int i = low, j = mid + 1, k = low;
// 将nums中的记录由小到大地并入temp中
while(i <= mid && j <= high){
if(nums[i] < nums[j])
temp[k++] = nums[i++];
else
temp[k++] = nums[j++];
}
// 对剩余的元素做处理
while(i <= mid) temp[k++] = nums[i++];
while(j <= high) temp[k++] = nums[j++];
// 这一步其实是多余的处理,不加这一步,sortArray中直接返回temp也行
for(int idx = low; idx <= high; idx++)
nums[idx] = temp[idx];
}
};