您的位置:首页 > 理论基础 > 数据结构算法

【数据结构与算法】快速排序

2016-11-15 15:27 162 查看
快速排序也使用了分治策略,它每次将待排序列分成两部分,前一部分的元素值都不比后一部分的元素值大。也就是前一部分都不比某个数大,后一部分都不比这个数小。这个基准的选择会直接影响快速排序的效率。

划分

固定第一个数为基准,以{5,4,3,5,6,12,11,-3,4,5,7}为例,用临时变量保存5,相当于挖了个坑,然后从后往前找到第一个小于基准的数,填入当前坑,原位置形成新坑,然后从前往后找到第一个大于基准的数继续填坑挖坑,最后将基准填入最后的坑。

基准为5,蓝色为左指针,红色为右指针操作
5,4,3,5,6,12,11,-3,4,5,7临时变量保存5,挖第一个坑
—,4,3,5,6,12,11,-3,4,5,7从后往前找第一个小于5的
4,4,3,5,6,12,11,-3,—,5,7填坑挖坑,从前往后找第一个大于5的
4,4,3,5,—,12,11,-3,6,5,7填坑挖坑,从后往前找第一个小于5的
4,4,3,5,-3,12,11,—,6,5,7填坑挖坑,从前往后找第一个大于5的
4,4,3,5,-3,—,11,12,6,5,7停止挖坑
4,4,3,5,-3,5,11,12,6,5,7将5填入最后一个坑
可以看出不能保证与基准相等的元素会集中到某一边,也不能集中到基准附近

private static int partition(int[] nums,int start,int end){
int t=nums[start];
int i=start,j=end;
while(i<j){
while(j>i&&nums[j]>=t){
j--;
}
nums[i]=nums[j];
while(i<j&&nums[i]<=t){
i++;
}
nums[j]=nums[i];
}
nums[i]=t;
return i;
}


如果基准位置为参数指定,代码为:

private static int partition(int[] nums,int start,int end,int pivot){
int t=nums[pivot]; //基准
int pit=pivot; //坑的位置
int i=start,j=end;
while(i<j){
while(j>i&&nums[j]>=t){
j--;
}
nums[pit]=nums[j];
pit=j;
while(i<j&&nums[i]<=t){
i++;
}
nums[pit]=nums[i];
pit=i;
}
nums[pit]=t;
return pit;
}


尝试很久写出不同思路的代码,但是好像没什么必要

private static int partition(int[] nums,int start,int end){
if(start>=end)return start;
int t=nums[start];
int i=start+1,j=end;
while(i<j){
while(nums[j]>=t&&j>i){  //从后往前找到第一个比t小的
j--;
}
while(i<j&&nums[i]<t){   //从前往后找到第一个不比t小的,注意是不比t小
i++;
}
if(i<j){
Swap.swap(nums, i, j);
}
}
//i有可能因为j的原因没有移动也没有比较
if(nums[i]<t){
Swap.swap(nums, start, i);
return i;
}else{
return i-1;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Java 排序