分治法
来完成的基准值
,然后从数组的两端开始移动查找,在右边
移动查找到比基准值
小的数据停止移动,此时在左边
查找到比基准值
大的数据也停止查找,交换
这两个查找到的数据,交换完成之后两端继续移动查找,如果左边找到比基准值大的,右边找到比基准值小的数据,再次交换。直到查找到同一个数据上(相遇)或者”擦肩而过”。那么将基准值
与相遇的那个值
交换,此时就能够保证在基准值左边的都是比基准值小的,在其右边的都是比其大的数,此时一轮查找结束。接下来这个基准值将一个数组分成了两半
,左边的是小的,右边是大的,那么我们再分别对左边和右边的数据进行相同的操作,直至不可拆分成新的子序列为止。O(n2)
,但期望的运行时间是O(nlgn)
。123456 | int[] array={ 9,7,4,67,45,2,24,33,22,45,88,12,1,0,25};quickSort(array, 0, array.length-1);for (int i = 0; i < array.length; i++) { System.out.print(array[i]+"\t");} |
---|
第一个元素
作为基准值public static void quickSort(int[] arr,int low,int high){
//递归结束的条件,如果此时的子序列只有一个元素就是low=high,就不用排序了
if(low>=high){
return;
}
int i=low; //i从最左边开始查找
int j=high; //i从最右边开始查找
int temp = arr[low]; //设置基准值为第一个元素,temp
//如果此时的i和j没有相遇,一直进行下去
while (i<j) {
//先从右边开始查找,如果没有找到比基准值小的并且没有相遇,那么继续向右查找
while (temp<=arr[j]&&i<j) {
j--; //向左移动
}
//再从左边开始查找,如果没有找到比基准值大的并且没有相遇,那么继续向左查找
while (temp>=arr[i]&&i<j) {
i++; // 向右移动
}
//代码能够运行到这里,那么表示已经找到了右面小于基准值的,左面大于基准值的,那么就可以交换数据了
//这里的i<j用于控制在最后相遇的时候还要交换数据,不必交换了,可以省去一次的交换
if (i<j) {
//交换数据
int t = arr[j];
arr[j] = arr[i];
arr[i] = t;
}
}
//最后将基准为与i和j相等位置的数字交换
arr[low] = arr[i]; //第一个元素设置为i和j相遇的那个值
arr[i] = temp; //相遇的那个地方设置为基准值
//递归调用左半数组,以基准值为中心切割
quickSort(arr, low, j-1);
//递归调用右半数组
quickSort(arr, j+1, high);
}
int[] array={ 9,7,4,67,45,2,24,33,22,45,88,12,1,0,25};
quickSort(array, 0, array.length-1);
for (int i = 0; i < array.length; i++) {
System.out.print(array[i]+"\t");
}
public static int partition(int[] array,int low,int high){
int i=low;
int j=high;
int temp=array[low]; //选取第一个为基准数
//如果此时的还没有相遇,表示没有结束
while(i<j){
//因为基准数是最左面的,因此从最右面开始查找
//当当前的值比基准值大,并且i和j不相等,即是没有相遇
while(temp<array[j]&&i<j){
j--; //向左移动,继续查找
}
//从左面开始查找,如果查找到的数据array[i]小于基准值并且i和j没有相遇,那么继续向右移动查找
while(array[i]<temp&&i<j){
i++; //继续向右移动查找
}
//代码能够运行到这里,那么表示已经找到了右面小于基准值的,左面大于基准值的,那么就可以交换数据了
if (i<j) {
int t = array[j];
array[j] = array[i];
array[i] = t;
}
}
low=i;
high=j;
return j ; //返回当前的基准值在数组中的索引,用于分割子序列
}
public static void quickSort1(int[] arrary,int low,int high){
//停止条件,如果low>high表示相遇,那么停止递归
if(low>high){
return;
}
int index=partition(arrary, low, high); //获取基准值的位置
quickSort1(arrary, low, index-1); //左边的
quickSort1(arrary,index+1,high); //右边的
}
最左边
开始查找,那么有可能某一次查找到了比基准值大的数,停止查找,等待最右边查找到比基准值小的数,但是此时最右边一直在查找,直到和其相遇都没有查找到比基准值小的数据,那么此时的的基准值就需要和这个比它还大的值交换,那么出现的结果就是此时的数组的第一个数是比基准值大的,违背了左边都是比基准值小的,右边都是比基准值大的。