快速排序
C++可以直接通过std::sort()快速排序,但是能够手写快排也是一件很重要的基础。
void quick_sort(vector<int> &nums,int l,int r)
{
if(l+1>=r)
{
return;
}
int first=l,last=r-1,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);
quick_sort(nums,first+1,r);
}
调用方式
sort(nums.begin(),nums.end());
quick_sort(nums,0,nums.size());
归并排序
void merge_sort(vector<int> &nums,intl,int r,vector<int> &temp)
{
if(l+1>=r)
{
return;
}
//divide
int m=l+(r-1)/2;
merge_sort(nums,l,m,temp);
merge_sort(nums,m,r,temp);
int p=l,q=m,i=l;
while(p<m||q<r)
{
if(q>=r||(p<m&&nums[p]<=nums[q]))
{
temp[i++]=nums[p++];
}
else
{
temp[i++]=nums[q++];
}
}
for(i=l;i<r;i++)
{
nums[i]=temp[i];
}
}
调用方式
merge_sort(nums,0,nums.size(),temp);
插入排序
void insertion_sort(vector<int> &nums,int n)
{
for(int i=0;i<n;++i)
{
for(int j=i;j>0&&nums[j]<nums[j-1];--j)
{
swap(nums[j],nums[j-1]);
}
}
}
调用方式
insertion_sort(nums,nums.size());
冒泡排序
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;
}
}
}
调用方式
bubble_sort(nums,nums.size());
选择排序
void selection_sort(vector<int> &nums,int n)
{
int mid;
for(int i=0;i<n-1;++i)
{
mid=i;
for(int j=1+i;j<n;++j)
{
if(nums[j]<nums[mid])
{
mid=j;
}
}
swap(nums[mid],nums[i]);
}
}
调用方式
selection_sort(nums,nums.size());
快速选择排序
快速选择一般用于求解K-th Element的问题,本质上是基于快排的算法,但是只用对满足条件的一侧进行排序就可以了。
int findKthLargest(vector<int> &nums,int k)
{
int l=0,r=nums.size()-1,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;
}
桶排序
桶排序一般有来解决带频率的排序,桶排序的意思是为每一个值设立一个桶,桶内记录这个值出现的次数然后对同排序。
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;
}
荷兰国旗问题排序
这个可参考下面这道leetcode
主要思路是通过双指针,一个标记0从左端开始,一个标记2从右端开始。
void sortColors(vector<int>& nums) {
int l=0,r=nums.size()-1;
int i=0;
while(i<=r)
{
if(nums[i]==0&&i!=l)
{
int temp=nums[l];
nums[l]=nums[i];
nums[i]=temp;
l++;
}
else if(nums[i]==2)
{
int temp=nums[r];
nums[r]=nums[i];
nums[i]=temp;
r--;
}
else i++;
}
}