LeetCode 这次写点不一样的(快排序,随机快排序,归并排序)

2那么还是我刘天昊

这次想和大家分享的是快排序和随机快排序的速度上的差异

那么算法导论里的老师(MIT的一个教授)说过随机快排序在大量的数据的情况下会比快排序好接近三倍

我觉得这句话是没问题的却是快了很多(三倍觉得略夸张)

那么leetcode好在哪里就是不用我们自己做测试集好我们来说说一个我们说过的问题

那么可以看我之前的博客里的这篇

Distribute Candies

这题虽然有更快的方案但是我主要说的是快排序和随机快排序的速度比较

先快排序代码不po了直接说5次的运行速度(leetcode每次的速度不一定一致虽然是一样的时间复杂度,never mind)

1.353ms

2.349ms

3.316ms

4.335ms

5.312ms

ok我们看到了接下来是随机快排序测试完后我会po上随机快排序的程序

1.252ms

2.272ms

3.262ms(-.-怎么都是2结尾,尴尬,如果不太信的话可以自己po代码跑)

4.252ms

5.269ms

我们可以看到即使是快排序的最快状态也比不过随机快排序的速度

好po上代码

void QuickSort(int *nums,int left,int right)
{
    if(left>right)
    {
        return ;
    }
    int i=Partition(nums,left,right);
    QuickSort(nums,left,i-1);
    QuickSort(nums,i+1,right);
}
int Partition(int *nums,int left,int right)
{
    int random=rand()%(right-left+1)+left;
    if(random>left&&random<right)
    {
        nums[random]=nums[random]^nums[left];
        nums[left]=nums[random]^nums[left];
        nums[random]=nums[random]^nums[left];
    }
    int pivot=nums[left];
    int i=left;
    int j=right;
    if(i>right)
    {
        return ;
    }
    while(i!=j)
    {
        while(nums[j]>=pivot&&i<j)
        {
            j--;
        }
        while(nums[i]<=pivot&&i<j)
        {
            i++;
        }
        if(i<j)
        {
            nums[j]=nums[j]^nums[i];
            nums[i]=nums[j]^nums[i];
            nums[j]=nums[j]^nums[i];
        }
    }
    nums[left]=nums[i];
    nums[i]=pivot;
    return i;
}
int distributeCandies(int* candies, int candiesSize) 
{
    int num=candiesSize/2;
    int res=0;
    QuickSort(candies,0,candiesSize-1);
    res++;
    for(int i=1;i<candiesSize;i++)
    {
        if(candies[i-1]!=candies[i])
        {
            res++;
        }
    }
    if(res>=num)
    {
        return num;
    }
    else
    {
        return res;
    }
    return 0;
}

这里可以看到快排序和随机快排序的代码区别就基准点是随机选取的

如果想要知道为什么随机快排序更快一些,可以去看算法导论或者联系我如果你想的话

644367822@qq.com

感觉这道题真的被我玩出花来了,今天试了试排序渐进最优的归并排序确实很快那么po上代码

void Merge(int *nums,int left,int mid,int right)
{
    int n1=mid-left+1;
    int n2=right-mid;
    int *nums1=(int *)malloc(sizeof(int )*n1);
    int *nums2=(int *)malloc(sizeof(int )*n2);
    for(int i=0;i<n1;i++)
    {
        nums1[i]=nums[left+i];
    }
    for(int i=0;i<n2;i++)
    {
        nums2[i]=nums[mid+1+i];
    }
    int i=0;
    int j=0;
    int k=left;
    while(i!=n1&&j!=n2)
    {
        if(nums1[i]<nums2[j])
        {
            nums[k++]=nums1[i++];
        }
        else
        {
            nums[k++]=nums2[j++];
        }
    }
    while(i!=n1)
    {
        nums[k++]=nums1[i++];
    }
    while(j!=n2)
    {
        nums[k++]=nums2[j++];
    }
    free(nums1);
    free(nums2);
}
void MergeSort(int *nums,int left,int right)
{
    if(left>=right)
    {
        return;
    }
    int mid=(right+left)/2;
    MergeSort(nums,left,mid);
    MergeSort(nums,mid+1,right);
    Merge(nums,left,mid,right);
}
int distributeCandies(int* candies, int candiesSize) 
{
    int num=candiesSize/2;
    int res=0;
    MergeSort(candies,0,candiesSize-1);
    res++;
    for(int i=1;i<candiesSize;i++)
    {
        if(candies[i-1]!=candies[i])
        {
            res++;
        }
    }
    if(res>=num)
    {
        return num;
    }
    else
    {
        return res;
    }
    return 0;
}
再来5次和随机快排序比较

1.209ms

2.199ms

3.206ms

4.225ms

5.212ms

看的出来快是确实快,(-。-我还一直以为随机快排序已经够吊的了)这些测试是基于leetcode这题的207个测试集,并没有具体的算法分析

只是跑个大概(比方说数很少的时候,插入比快排序还快,不能一概而论,只是针对这题的测试集而言)不过也能说明一些问题了


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值