第5章千奇百怪的排序算法
内容提要
项目 | Value |
---|---|
排序算法 | 常用排序算法 桶排序 快速排序 |
常用排序
快速排序
void quick_sort(int a[],int l,int r)
{
if (l >= r) return;
int i = l - 1, j = r + 1, x = a[l + r >> 1];
while (i < j)
{
do i++; while(a[i] < x);
do j--; while(a[j] > x);
if (i < j) swap(a[i], a[j]);
}
quick_sort(a, l, j);
quick_sort(a, j + 1, r);
}
归并排序
#include <iostream>
using namespace std;
const int N = 1e6 + 10;
int a[N], tmp[N];
void merge_sort(int q[], int l, int r)
{
if (l >= r) return;
int mid = l + r >> 1;
merge_sort(q, l, mid), merge_sort(q, mid + 1, r);
int k = 0, i = l, j = mid + 1;
while (i <= mid && j <= r)
if (q[i] <= q[j]) tmp[k ++ ] = q[i ++ ];
else tmp[k ++ ] = q[j ++ ];
while (i <= mid) tmp[k ++ ] = q[i ++ ];
while (j <= r) tmp[k ++ ] = q[j ++ ];
for (i = l, j = 0; i <= r; i ++, j ++ ) q[i] = tmp[j];
}
int main()
{
int n;
scanf("%d", &n);
for (int i = 0; i < n; i ++ ) scanf("%d", &a[i]);
merge_sort(a, 0, n - 1);
for (int i = 0; i < n; i ++ ) printf("%d ", a[i]);
return 0;
}
插入排序(Insertion Sort):
void insertion_sort(vector<int>& nums, int n)
{
for (int i = 1; i < n; ++i)
{
for (int j = i; j > 0 && nums[j] < nums[j - 1]; --j)
{
swap(nums[j], nums[j - 1]);
}
}
}
冒泡排序(Bubble Sort):
void bubble_sort(vector<int>& nums, int n)
{
bool swapped;
for (int i = 1; i < n; ++i)
{
swapped = false;
for (int j = 1; j < n - i + 1; ++j)
{
if (nums[j] < nums[j - 1])
{
swap(nums[j], nums[j - 1]);
swapped = true;
}
}
if (!swapped)
{
break;
}
}
}
5.2快速选择
215.Kth Largest Element in an Array
int findKthLargest(vector<int>& nums, int k) {
int l = 0, r = nums.size() - 1;
int target = nums.size() - k;
while (l < r) {
int mid = quickSelection(nums, l, r);
if (mid == target)
return nums[mid];
if (mid < target)
l = mid + 1;
else
r = mid - 1;
}
return nums[l];
}
int quickSelection(vector<int>& nums, int l, int r) {
int i = l + 1, j = r;
while (true) {
while (i <= r && nums[i] < nums[l])
++i;
while (l < j && nums[j] > nums[l])
--j;
if (i >= j)
break;
swap(nums[i], nums[j]);
}
swap(nums[l], nums[j]);
return j;
}
在主函数 findKthLargest
中,使用 l
和 r
表示当前待搜索的区间范围,target
表示目标位置的索引。通过不断使用快速选择算法 quickSelection
来缩小搜索区间,直到找到目标位置或搜索区间为空。在辅助函数 quickSelection
中,使用双指针的方式来进行快速选择,将小于目标值的元素放在左边,大于目标值的元素放在右边,最后返回目标值的索引。
5.3桶排序
347.Top K Frequent Elements (Medium)
vector<int> topKFrequent(vector<int>& nums, int k) {
unordered_map<int, int> counts;
int max_count = 0;
for (const int num : nums) {
max_count = max(max_count, ++counts[num]);
}
vector<vector<int>> buckets(max_count + 1);
for (const auto& p : counts) {
buckets[p.second].push_back(p.first);
}
vector<int> ans;
for (int i = max_count; i >= 0 && ans.size() < k; --i) {
for (const int num : buckets[i]) {
ans.push_back(num);
if (ans.size() == k) {
break;
}
}
}
return ans;
}
#include <iostream>
#include <vector>
void quick_sort(std::vector<int> &nums, int l, int r);
void print_array(const std::vector<int> &nums);
int main()
{
std::cout << "Hello, World!" << std::endl;
std::vector<int> a = {3, 5, 3, 7, 2, 88, 55, 33, 55, 222, 11, 11, 23, 45, 56};
quick_sort(a, 0, a.size() - 1);
print_array(a);
return 0;
}
void quick_sort(std::vector<int> &nums, int l, int r)
{
if (l >= r)
return;
int first = l, last = r, key = nums[first];
while (first < last)
{
while (first < last && nums[last] >= key)
{
--last;
}
nums[first] = nums[last];
while (first < last && nums[first] <= key)
{
++first;
}
nums[last] = nums[first];
}
nums[first] = key;
quick_sort(nums, l, first - 1);
quick_sort(nums, first + 1, r);
}
void print_array(const std::vector<int> &nums)
{
for (int i = 0; i < nums.size(); i++)
{
std::cout << nums[i] << " ";
}
std::cout << std::endl;
}