(算法)快速排序————<分治-快排>

1. 题⽬链接:912.排序数组

2. 题⽬描述:

3. 解法(数组分三块思想+随机选择基准元素的快速排序):

算法思路:

我们在数据结构阶段学习的快速排序的思想可以知道,快排最核⼼的⼀步就是Partition(分割数 据):将数据按照⼀个标准,分成左右两部分。

如果我们使⽤荷兰国旗问题的思想,将数组划分为左中右三部分:左边是⽐基准元素⼩的数据, 中间是与基准元素相同的数据,右边是⽐基准元素⼤的数据。然后再去递归的排序左边部分和右边 部分即可(可以舍去⼤量的中间部分)。

在处理数据量有很多重复的情况下,效率会⼤⼤提升。

算法流程:

随机选择基准算法流程:

函数设计:int randomKey(vector& nums, int left, int right)

a. 在主函数那⾥种⼀颗随机数种⼦;

b. 在随机选择基准函数这⾥⽣成⼀个随机数;

c. 由于我们要随机产⽣⼀个基准,因此可以将随机数转换成随机下标:让随机数%上区间⼤⼩, 然后加上区间的左边界即可。

快速排序算法主要流程:

a. 定义递归出⼝;

b. 利⽤随机选择基准函数⽣成⼀个基准元素;

c. 利⽤荷兰国旗思想将数组划分成三个区域;

d. 递归处理左边区域和右边区域。

C++算法代码: 

class Solution 
{
public:
    //快排
    void qsort(vector<int>& nums,int l,int r)
    {
        if(l>=r)
        {
            return;
        }
        //取随机关键字
        int key=nums[rand()%(r-l+1)+l];
        //数据分三块
        小于   等于    大于
        int left=l-1,right=r+1,i=l;
        while(i<right)
        {
            if(nums[i]<key)
            {
                swap(nums[i++],nums[++left]);
            }
            //大于的数据交换后有可能还不符合条件,所以不能i++
            else if(nums[i]>key)
            {
                swap(nums[i],nums[--right]);
            }
            else
            {
                i++;
            }
        }
        //小于的部分排序
        qsort(nums,l,left);
        //大于的部分排序
        qsort(nums,right,r);
    }
    vector<int> sortArray(vector<int>& nums) 
    {
        //种随机数种子
        srand(time(NULL));
        qsort(nums,0,nums.size()-1);
        return nums;
    }
};

 Java算法代码:

class Solution
{
	public int[] sortArray(int[] nums)
	{
		qsort(nums, 0, nums.length - 1);
		return nums;
	}
	public void qsort(int[] nums, int l, int r)
	{
		if (l >= r) return;
		// 数组分三块 
		int key = nums[new Random().nextInt(r - l + 1) + l];
		int left = l - 1, right = r + 1, i = l;
		while (i < right)
		{
			if (nums[i] < key) swap(nums, ++left, i++);
			else if (nums[i] == key) i++;
			else swap(nums, --right, i);
		}
		// [l, left] [left + 1, right - 1] [rigth, r]
		qsort(nums, l, left);
		qsort(nums, right, r);
	}
	public void swap(int[] nums, int i, int j)
	{
		int t = nums[i];
		nums[i] = nums[j];
		nums[j] = t;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

课堂随笔

感谢支持~~~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值