快速排序
快速排序(Quicksort)是对冒泡排序的一种改进。
快速排序由C. A. R. Hoare在1960年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
具体思路为,将快速排序分为两个部分。
先创建一个随机数列
int[] value=new int[15];
for (int i = 0; i < value.length; i++) {
value[i]=(int)(Math.random()*100);
}
System.out.println(Arrays.toString(value));
再新建一个快速排序方法
- 将第一个值作为参照值,与下标i的值和下标j的值进行比较。
- 在循环中,i或者j的下标上的数必定是参照值,
- 当参照值大于j下标的值时,则代表参照值在i下标上,将i、j互换,因此就将比参照值大的值放在了参照值的右方。
- 如果参照值不大于j下标的值,则j–,继续循环,直到找到大于j下标的值,或者i与j的值相等。
- 当参照值小于i下标的值时,则代表参照值在j下标上,将i、j互换,因此就将比参照值小的值放在了参照值的左方。
- 如果参照值不小于j下标的值,则i++,继续循环,直到找到小于i下标的值,或者i与j的值相等。
- 当i和j相等时,结束所有循环
- 当i和j相等时,可以得到数组:
- 比参照值小的数都在参照值左边,比参照值大的数都在参照值右边。
- 当i和j相等时,可以得到数组:
public static void quickSort(int[] value){
int number=value[0];
int i=0;
int j=value.length-1;
while (i<j){ //当i=j时,退出循环
while (i<j){
if (number>value[j]) { //当第一个数大于j下标数时,将下标i的值与下标j的值互换
value[i]=value[i]^value[j];
value[j]=value[i]^value[j];
value[i]=value[i]^value[j];
break;
} else{
j--; //如果第一个数不大于最后一个数,则j--
}
}
while (i<j){
if (number<value[i]) { //当第一个数小于i下标数时,将i、j的值互换
value[i]=value[i]^value[j];
value[j]=value[i]^value[j];
value[i]=value[i]^value[j];
break;
} else{
i++;
}
}
}
}
以上代码执行后可以得到如下情况:
[39, 3, 94, 70, 5, 30, 52, 66, 29, 84] //代码执行前的随机数组
[29, 3, 30, 5, 39, 70, 52, 66, 94, 84] //代码执行后的数组
因此,第一层快速排序方法便完成了。
接下来将利用递归
一直循环以上排序方法,便可以得到一个由小到大的有序数列
引入起始到结束之间的范围,第一次循环为全部数组
左侧循环则是第一个值和对比值之间,即start~(i-1)
依次循环,直到所有数循环完毕 开始右侧循环
右侧循环是最后一个值和对比值之间,即(i+1)~end
依次循环,直到所有数循环完毕。
public static void main(String[] args) {
int[] value=new int[10];
for (int i = 0; i < value.length; i++) {
value[i]=(int)(Math.random()*100);
}
System.out.println(Arrays.toString(value));
quickSort(value,0, value.length-1);
System.out.println(Arrays.toString(value));
}
public static void quickSort(int[] value,int start,int end){
int number=value[start]; //以每次起始位置的值作为对比值
int i=start; //i的值为每次循环的起始位置,
int j=end; //j的值为每次循环的结束位置。
while (i<j){ //当i=j时,退出循环
while (i<j){
if (number>value[j]) { //当对比值大于j下标数时,将下标i的值与下标j的值互换
value[i]=value[i]^value[j];
value[j]=value[i]^value[j];
value[i]=value[i]^value[j];
break;
} else{
j--; //如果第一个数不大于最后一个数,则j--
}
}
while (i<j){
if (number<value[i]) { //当对比值小于i下标数时,将i、j的值互换
value[i]=value[i]^value[j];
value[j]=value[i]^value[j];
value[i]=value[i]^value[j];
break;
} else{
i++;
}
}
}
if (i-start>1) { //当i与起始值之间有两个及以上个数时,则再次进行递归,
quickSort(value,start,i-1); //起始位置不变,结束位置为上一个中间值的左边一个数
}
if(end-i>1){ //当i与结束值之间有两个及以上个数时,则再次进行递归,
quickSort(value, i+1, end); //结束位置不变,起始位置为上一个中间值的右边一个数
}
}
结果示例:
[80, 52, 94, 62, 12, 99, 27, 50, 37, 37]
[12, 27, 37, 37, 50, 52, 62, 80, 94, 99]
[35, 47, 46, 54, 45, 1, 96, 46, 66, 60]
[1, 35, 45, 46, 46, 47, 54, 60, 66, 96]
[80, 41, 68, 82, 97, 43, 14, 57, 26, 48]
[14, 26, 41, 43, 48, 57, 68, 80, 82, 97]
完整代码如下
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
int[] value=new int[10];
for (int i = 0; i < value.length; i++) {
value[i]=(int)(Math.random()*100);
}
System.out.println(Arrays.toString(value));
quickSort(value,0, value.length-1);
System.out.println(Arrays.toString(value));
}
public static void quickSort(int[] value,int start,int end){
int number=value[start]; //以每次起始位置的值作为对比值
int i=start; //i的值为每次循环的起始位置,
int j=end; //j的值为每次循环的结束位置。
while (i<j){ //当i=j时,退出循环
while (i<j){
if (number>value[j]) { //当第一个数大于j下标数时,将下标i的值与下标j的值互换
value[i]=value[i]^value[j];
value[j]=value[i]^value[j];
value[i]=value[i]^value[j];
break;
} else{
j--; //如果第一个数不大于最后一个数,则j--
}
}
while (i<j){
if (number<value[i]) { //当第一个数小于i下标数时,将i、j的值互换
value[i]=value[i]^value[j];
value[j]=value[i]^value[j];
value[i]=value[i]^value[j];
break;
} else{
i++;
}
}
}
if (i-start>1) { //当i与起始值之间有两个及以上个数时,则再次进行递归,
quickSort(value,start,i-1); //起始位置不变,结束位置为上一个中间值的左边一个数
}
if(end-i>1){ //当i与结束值之间有两个及以上个数时,则再次进行递归,
quickSort(value, i+1, end); //结束位置不变,起始位置为上一个中间值的右边一个数
}
}
}