快速排序总结
思路
快速排序将一个集合分成两个区域,一个区域中的所有元素都比另外一个区域中的元素小。对分出来的区域再次进行划分,不断划分后,会形成一个完全有序的集合。
算法
参数
- 待排序集合
- 待排序区域的左边界索引
- 待排序区域的有边界索引
返回值
快速排序无返回值
步骤
- 1:判断递归终止条件
- 条件:待排序区域的左边界与右边界是否相等。
- 2:参数初始化
- key:用来区分两个区域的值,左边区域所有区域都比key值小,右边区域都比key值大。 --初始化为最左边元素的值
- i:左边区域的右边界。(后面意义会变)最左边元素的索引
- j:右边区域的左边界。(后面意义会变)最右边元素的索引
- 3:迭代,交换乱序区域的值,使之形成相对有序的两个区域
- i值不断加一直到遇到一个索引处值比key值大的数且i不能超出右边界
- j值不断减一直到遇到一个索引处值比key值小的数且j不能超出左边界
- 判断i是否大于j,如果大于j则推出迭代(大于说明,两块区域已经分好,此时j代表的是左边区域的右边界(从右往左的第一个比key值小的数);i代表的是右边区域的左边界(从左往右的第一个比key值大的数)。)
- 交换i对应索引处与j对应索引处的值(交换后,左边区域少了个比key值大的,多了个比key值小的;右边同理)
- 4:交换key值
将key值对应索引(左边边界)与j对应索引处值(左边区域的右边界)进行交换,至此两个区域才算真正分好。key值左边都比它小,右边都比它大。key的索引在 j 对应的位置。 - 5:对得到的两个区域进行递归
-左边区域: (左边界, j-1)
-右边区域: (j+1, 右边界)
(j:key值交换后对应的索引)
代码如下
public void qsort(int[] nums, int low, int high){
if(low >= high)
return;
int key = nums[low];
int i = low; //key值在low处,但由于下面的循环使用的是先加加,所以初始化为low
int j = high+1;//由于循环用的是先减减,所以加了1。
while(true){
while(nums[++i]<key){
if(i==high)
break;
}
while(nums[--j]>key){
if(j==low)
break;
}
if(i>=j)
break;
int tmp = nums[j];
nums[j] = nums[i];
nums[i] = tmp;
}
int tmp = nums[j];
nums[j] = key;
nums[low] = tmp;
qsort(nums, low, j-1);
qsort(nums, j+1, high);
}