[算法] 排序
排序算法有很多种类,可以从时空复杂度、稳定性等角度来分析。
排序算法 | 平均时间复杂度 | 最坏时间复杂度 | 最好时间复杂度 | 空间复杂度 | 稳定性 |
---|---|---|---|---|---|
快速排序 | 不稳定 | ||||
冒泡排序 | 稳定 | ||||
归并排序 | 稳定 | ||||
选择排序 | 不稳定 | ||||
堆排序 | 不稳定 | ||||
插入排序 | 稳定 | ||||
希尔排序 | 不稳定 | ||||
计数排序 | 稳定 | ||||
桶排序 | 稳定 | ||||
基数排序 | 稳定 |
1. 快速排序
class Solution {
private:
int partition(vector<int> &nums, int lo, int hi) {
swap(nums[lo], nums[lo + rand() % (hi - lo + 1)]);
int pivot = nums[lo];
while (lo < hi) {
while (lo < hi && pivot <= nums[hi])
--hi;
nums[lo] = nums[hi];
while (lo < hi && nums[lo] <= pivot)
++lo;
nums[hi] = nums[lo];
}
nums[lo] = pivot;
return lo;
}
void quickSort(vector<int> &nums, int lo, int hi) {
if (lo >= hi)
return;
int mi = partition(nums, lo, hi);
quickSort(nums, lo, mi - 1);
quickSort(nums, mi + 1, hi);
}
public:
vector<int> sortArray(vector<int>& nums) {
int n = nums.size();
quickSort(nums, 0, n - 1);
return nums;
}
};
2. 冒泡排序
class Solution {
private:
void bubbleSort(vector<int> &nums) {
int n = nums.size();
for (int i = n; i >= 2; --i) {
bool noSwap = true;
for (int j = 0; j < i - 1; ++j) {
if (nums[j] > nums[j + 1]) {
swap(nums[j], nums[j + 1]);
noSwap = false;
}
}
if (noSwap)
break;
}
}
public:
vector<int> sortArray(vector<int>& nums) {
bubbleSort(nums);
return nums;
}
};
3. 归并排序
class Solution {
private:
void merge(vector<int> &nums, int lo, int mi, int hi) {
vector<int> temp(hi - lo);
int i = lo, j = mi, k = 0;
while (i < mi && j < hi) {
if (nums[i] <= nums[j])
temp[k++] = nums[i++];
else
temp[k++] = nums[j++];
}
while (i < mi)
temp[k++] = nums[i++];
while (j < hi)
temp[k++] = nums[j++];
for (i = lo, k = 0; i < hi; ++i, ++k)
nums[i] = temp[k];
}
void mergeSort(vector<int> &nums, int lo, int hi) {
if (lo + 1 >= hi)
return;
int mi = (lo + hi) / 2;
mergeSort(nums, lo, mi);
mergeSort(nums, mi, hi);
merge(nums, lo, mi, hi);
}
public:
vector<int> sortArray(vector<int>& nums) {
int n = nums.size();
mergeSort(nums, 0, n);
return nums;
}
};
4. 选择排序
class Solution {
private:
void selectionSort(vector<int> &nums) {
int n = nums.size();
for (int i = n; i >= 2; --i) {
int maxIdx = 0;
for (int j = 0; j < i; ++j)
if (nums[j] > nums[maxIdx])
maxIdx = j;
swap(nums[maxIdx], nums[i-1]);
}
}
public:
vector<int> sortArray(vector<int>& nums) {
selectionSort(nums);
return nums;
}
};
5. 堆排序
class Solution {
private:
void siftDown(vector<int> &nums, int start, int end) {
int parent = start;
int child = parent * 2 + 1;
while (child <= end) {
if (child + 1 <= end && nums[child] < nums[child + 1])
++child;
if (nums[parent] >= nums[child])
return;
swap(nums[parent], nums[child]);
parent = child;
child = parent * 2 + 1;
}
}
void heapSort(vector<int> &nums) {
int n = nums.size();
for (int i = (n - 2) / 2; i >= 0; --i)
siftDown(nums, i, n - 1);
for (int i = n - 1; i >= 0; --i) {
swap(nums[0], nums[i]);
siftDown(nums, 0, i - 1);
}
}
public:
vector<int> sortArray(vector<int>& nums) {
heapSort(nums);
return nums;
}
};
6. 插入排序
class Solution {
private:
void insertionSort(vector<int> &nums) {
int n = nums.size();
for (int i = 1; i < n; ++i) {
int target = nums[i], j = i - 1;
while (j >= 0 && target < nums[j]) {
nums[j + 1] = nums[j];
--j;
}
nums[j + 1] = target;
}
}
public:
vector<int> sortArray(vector<int>& nums) {
insertionSort(nums);
return nums;
}
};
7. 希尔排序
class Solution {
private:
void shellSort(vector<int> &nums) {
int n = nums.size();
for (int gap = n / 2; gap >= 1; gap /= 2) {
for (int i = 0; i < gap; ++i) {
for (int j = i + gap; j < n; j += gap) {
int target = nums[j], k = j - gap;
while (k >= 0 && target < nums[k]) {
nums[k + gap] = nums[k];
k -= gap;
}
nums[k + gap] = target;
}
}
}
}
public:
vector<int> sortArray(vector<int>& nums) {
shellSort(nums);
return nums;
}
};
8. 计数排序
class Solution {
private:
void countingSort(vector<int> &nums, int minVal, int maxVal) {
vector<short> count(maxVal - minVal + 1, 0);
for (int &num : nums)
count[num - minVal] += 1;
int idx = 0;
for (int i = minVal; i <= maxVal; ++i) {
while (count[i - minVal] > 0) {
nums[idx++] = i;
count[i - minVal] -= 1;
}
}
}
public:
vector<int> sortArray(vector<int>& nums) {
countingSort(nums, -50000, 50000);
return nums;
}
};
9. 桶排序
class Solution {
private:
void bucketSort(vector<int> &nums, int minVal, int maxVal) {
int n = nums.size();
int bucketNum = (maxVal - minVal) / n + 1;
vector<vector<int> > buckets(bucketNum, vector<int>());
for (int &num : nums)
buckets[(num - minVal) / n].push_back(num);
int idx = 0;
for (auto &bucket : buckets) {
sort(bucket.begin(), bucket.end());
for (int &num : bucket)
nums[idx++] = num;
}
}
public:
vector<int> sortArray(vector<int>& nums) {
bucketSort(nums, -50000, 50000);
return nums;
}
};
10. 基数排序
class Solution {
private:
void radixSort(vector<int> &nums, int minVal, int maxVal) {
int newMaxVal = maxVal - minVal;
int maxDigit = 0;
while (newMaxVal) {
maxDigit += 1;
newMaxVal /= 10;
}
vector<vector<int> > buckets(10, vector<int>());
int div = 1;
for (int i = 0; i < maxDigit; ++i) {
for (auto &bucket : buckets)
bucket.clear();
for (int &num : nums)
buckets[(num - minVal) / div % 10].push_back(num);
int idx = 0;
for (auto &bucket : buckets)
for (int &num : bucket)
nums[idx++] = num;
div *= 10;
}
}
public:
vector<int> sortArray(vector<int>& nums) {
radixSort(nums, -50000, 50000);
return nums;
}
};
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库