快排的2种分区图解
作者:互联网
图解2种快排分区
主要是找分区点后把小于分区点值的放在左边,大于分区点的放在右边
关键点是如何找到这个分区点应该放的位置
分区方式1
选取最右边的3做分区点 privot 把小于privot的放在左边 按照同样的逻辑处理左边区间的数据 把大于privot的放在右边 按照同样的逻辑处理右边区间的数据
假设要把privot放在i的位置
- 那么要有2个区间 ,最终实现的效果
- [p,i-1]放小于privot的元素
- [i+1,r] 放大于privot的元素
- i 放pivot
arr[i]是第一个大于privot的,在i之后都是大于privot的, 如果在遍历过程中发现了比privot小的数, 要把这个数与arr[i] 交换,同时i++才能保证arr[i]是第一个大于privot的位置 遍历[p,r-1] 把小于分区点arr[r]的放入到[p,r-1] 最后把分区点挪到分区点索引i,并返回i
下面是1个分区过程图
代码如下
int partition(int arr[],int p,int r){ int privot=arr[r];//分区点 int i,j; //arr[p,i-1]为已处理区间 i=p,j=p; for(;j<r-1;j++){ if(arr[j]<privot){ int tmp=arr[i]; arr[i]=arr[j]; arr[j]=tmp; i++; } } arr[r]=arr[i]; arr[i]=privot; return i; }
分区方式2
两端指针
把其中的一个挖出来,作为分隔点,这端就会有1个坑 从另外1端开始,考察元素 ,大于分隔点的挖出这个元素 移动到另外1端的坑处, 没坑的这端向中间移动,考察这端的元素与privot...具体看下图 总之就是 1.挖坑 2.对端考察(与privot比较) 比较的结果是 1.向中央移动 继续与privot比较 2.挖出来填到对端坑,对端向中央移动,考察 移动或者挖出
这种方式的分区代码
function partition1(&$arr,$left,$right){ $privot=$arr[$right]; while($left<$right) { while($arr[$left]<$privot && $left<$right){ $left++; } if($arr[$left]>$privot && $left<$right){ $arr[$right]=$arr[$left]; $right--; } while($arr[$right]>$privot && $left<$right){ $right--; } if($arr[$right]<$privot && $left<$right){ $arr[$left]=$arr[$right]; $left++; } } $arr[$left]=$privot; return $left; }
在排序过程中 原有的大小顺序(456)被打乱,所以快排不是稳定排序算法
标签:arr,privot,分区,快排,int,大于,图解,left 来源: https://blog.51cto.com/huangkui/2677733