Leetcode912.排序数组(三路划分)


一、三路划分

为何还会有三路划分?

快速排序算法在某个数据大量重复时效率极低,在运行程序时会超出时间限制,为了解决数据大量重复的情况下,三路划分诞生了。三路划分是基于快速排序思想上的,三路划分在于解决数据中有大量重复或者几乎为同一个数据时想出来的,但是对于一般的数据也可以排序。

三路划分思想

三路划分是基于快速排序思想,选出数据中的关键字(随机选数选出关键字),然后对这个关键字(key)进行单趟排序,使小于key的值甩到key的左边,将大于key的值甩到右边,而中间很大一部分区间的值是相同的。中间相等的区间就不用再处理,对这个关键字它的左区间进行相同处理,右区间进行相同处理,对相等值区间不再处理。
在这里插入图片描述

三指针实现,left,cur,right选出关键字如果随机选取之后左边做关键字key=a[left]则从左边走,此时cur = left+1,如果随机选取之后右边做关键字key = a[right],则cur = right-1,从右边开始走。cur对应得值与关键字key比较,·当a[cur] == key,cur++;当a[cur] < key,就将a[cur]与a[left],此时cur++,left++,当a[cur] > key,将a[right]与a[cur]交换,此时right--,cur不动,由于并不知道交换过来的值是大于还是小于或者等于关键字key,直到cur走到超过right为止。这样一趟排下来会得到区间right - left中的值是相同,区间[begin,left]值小于key,区间[right+1,end]值大于key,这时也就划分为了三个区间(小于、等于、大于)。这样的方法也很类似快排的前后指针法。
在这里插入图片描述
一趟排之后划分出三个区间
在这里插入图片描述

二、Leetcode912.排序数组

在这里插入图片描述
在这里插入图片描述

返回的数组必须是自己malloc出来的

在这里插入图片描述

返回数组首元素地址

在这里插入图片描述

返回的这个数组有多大

用快排三路划分将数组排序

void Swap(int* e1, int* e2)
{
	int tmp = *e1;
	*e1 = *e2;
	*e2 = tmp;
}

void QuickSort(int*a,int left,int right)
{
	//当区间大小为1或者不存在就不需要单趟排序了
    if(left>=right)
    {
        return ;
    }
	//随机选数
    int randi = left + (rand() % (right - left));
	if (randi != left)
	{
		Swap(&a[randi], &a[left]);//以左边做关键值
	}

    int begin = left;
    int key = a[left];//以左边做关键值
    int end = right;
    int cur = left+1;//类似前后指针法

    while(cur<=right)
    {
        if(a[cur] < key)//当前值小于key,交换,两者都向后移动
        {
            Swap(&a[cur], &a[left]);
            cur++;
            left++;
        }

        else if(a[cur]>key)//大于时与最右边的交换,然后right--,
        //由于最开始并不确定a[left]与key关系,所以交换后cur不动
        {
            Swap(&a[cur], &a[right]);
            right--;
        }

        else
        {
            cur++;
        }
    }
    //类似普通快排递归排key值对应区间它的左区间
    QuickSort(a,begin,left-1);
    //递归排key值对应区间它的右区间
    QuickSort(a,right+1,end);
	
	//关键字对应区间不需要处理
}

int* sortArray(int* nums, int numsSize, int* returnSize){
  int*a = (int*)malloc(sizeof(int)*numsSize);
  *returnSize = 0;
   QuickSort(nums,0,numsSize-1);
   //将排好序的数组依次赋值给malloc出来的数组
   for(int i = 0; i<numsSize;i++)
   {
       a[(*returnSize)++] = nums[i];
   }
   
   return a;//返回malloc出来的数组a的首地址
}

三路划分用于解决对大量重复的数据进行排序的问题。

  • 34
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 27
    评论
评论 27
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值