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个测试集,并没有具体的算法分析
只是跑个大概(比方说数很少的时候,插入比快排序还快,不能一概而论,只是针对这题的测试集而言)不过也能说明一些问题了