快速排序思想:
1.选择数组左边(或者右边最后一个)第一个元素为基准,把数组所有元素比基准大的放在数组右边,比基准小的放在左边 ,然后将最左边的基准值放到对应的位置,这时基准的位置就正确了,在去调整其他数字的位置。思想就是不断调整基准值的过程。
(复杂度为O(n))
2.对基准左右两边的序列分别进行快速排序。
快速排序的最差时间复杂度和冒泡排序是一样的都是O(N2),它的平均时间复杂度为O(NlogN)。
/**
* @author yin
* @Date 2019/8/4 12:00
* @Method
*/
public class Demo2 {
//三数取中
public static int GetMid(int[] array, int left, int right) {
// assert(array);
int mid = left + ((right - left) >> 1);
if (array[left] <= array[right]) {
if (array[mid] < array[left])
return left;
else if (array[mid] > array[right])
return right;
else
return mid;
} else {
if (array[mid] < array[right])
return right;
else if (array[mid] > array[left])
return left;
else
return mid;
}
}
public static void quickSort(int[] arr ,int left, int right) {
if (left > right) {
return;
}
// int temp = arr[left];
//在排序数组中 将开始 中间 末尾 三个字段取中间大小的下标
int a= GetMid(arr, left, right);
int temp3 = arr[a];
arr[a]=arr[left];
arr[left] = temp3;
int temp = arr[left];
int temp_left=left;
int temp_right=right;
//在当前数组中让左边小于临时比对值 右边都大于临时比对值
while (temp_left < temp_right) {
//此处需要特别注意 必须先-- 后面 再 ++,快速排序 需要先对基准值的对面进行操作,(如果以数组的右边为基准,则需要先++,再--)
while (arr[temp_right] >= temp && temp_left < temp_right) {
temp_right--;
}
while (arr[temp_left] <= temp && temp_left < temp_right) {
temp_left++;
}
if (temp_left < temp_right) {
int temp2 = arr[temp_left];
arr[temp_left]=arr[temp_right];
arr[temp_right] = temp2;
}
}
arr[left] = arr[temp_left];
arr[temp_left]=temp;
//再在左边进行排序
quickSort(arr, left, temp_right - 1);
//右边进行排序
quickSort(arr, temp_right + 1, right);
}
public static void swap(int[] arr, int a, int b) {
int temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
public static void main(String[] args) {
int arr[] = {5, 5, 6, 2, 7, 10, 45, 1, 3, 2, 8};
quickSort(arr, 0, arr.length-1);
for (int i : arr) {
System.out.println(i);
}
}
}
这里两个while的顺序是不能改变的,如果先按基准值那边数值先++,就有可能导致while循环在比基准大的地方停止,然后交换顺序。导致比基准值更大的数值交换到前面去了,如果先–不满足while循环的temp_left的值一定是小于基准值的。