德鲁周记07--千奇百怪的排序算法(排序算法总结)持续更新补充

快速排序

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++;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值