基本思想:
快速排序是我们之前学习的冒泡排序的升级,他们都属于交换类排序,都是采用不断的比较和移动来实现排序的。快速排序是一种非常高效的排序算法,它的实现,增大了记录的比较和移动的距离,将关键字较大的记录从前面直接移动到后面,关键字较小的记录从后面直接移动到前面,从而减少了总的比较次数和移动次数。同时采用“分而治之”的思想,把大的拆分为小的,小的拆分为更小的,其原理如下:对于给定的一组记录,选择一个基准元素,通常选择第一个元素或者最后一个元素,通过一趟扫描,将待排序列分成两部分,一部分比基准元素小,一部分大于等于基准元素,此时基准元素在其排好序后的正确位置,然后再用同样的方法递归地排序划分的两部分,直到序列中的所有记录均有序为止。
Java实现1如下:
public class NiukeTest
{
@Test
public void Test()
{
int[] arr = { 49, 38, 65, 97, 23, 22, 76, 1, 5, 8, 2, 0, -1, 22 };
System.out.println("排序前: ");
for (int i = 0; i < arr.length; i++) {
System.out.printf(arr[i] + " ");
}
System.out.println();
quickSort(arr, 0, arr.length - 1);
System.out.println("排序后: ");
for (int i = 0; i < arr.length; i++) {
System.out.printf(arr[i] + " ");
}
}
private static void quickSort(int[] arr, int low, int high)
{
if(low < high){
//寻找基准数据的正确索引
int index = getIndex(arr, low, high);
//进行递归对index之前和之后
quickSort(arr, low, index - 1);
quickSort(arr, index + 1, high);
}
}
//寻找基准数据的正确索引
private static int getIndex(int[] arr, int low, int high){
//基准数据
int tmp = arr[low];
while (low < high){
//当队尾元素小于等于tmp时,向前挪动low
while (low < high && arr[high] >= tmp){
high--;
}
//如果队尾元素小于tmp了,需要将其赋值给low
arr[low] = arr[high];
//当队首元素小于等于tmp时,向前挪动low
while (low < high && arr[low] <= tmp){
low++;
}
arr[high] = arr[low];
}
//跳出循环时low和high相等,此时的low或high就是tmp的正确索引位置
arr[low] = tmp;
return low; //返回tmp的正确位置
}
}
Java实现2如下:
package sort;
import java.util.Arrays;
public class QuickSort
{
private static int partition(int[] arr, int low, int high)
{
//指定左指针i和右指针j
int i = low;
int j= high;
//将第一个数作为基准值。挖坑
int x = arr[low];
//使用循环实现分区操作
while(i<j)
{//5 8
//1.从右向左移动j,找到第一个小于基准值的值 arr[j]
while(arr[j]>=x && i<j)
{
j--;
}
//2.将右侧找到小于基准数的值加入到左边的(坑)位置, 左指针想中间移动一个位置i++
if(i<j)
{
arr[i] = arr[j];
i++;
}
//3.从左向右移动i,找到第一个大于等于基准值的值 arr[i]
while(arr[i] < x && i < j)
{
i++;
}
//4.将左侧找到的打印等于基准值的值加入到右边的坑中,右指针向中间移动一个位置 j--
if(i<j)
{
arr[j] = arr[i];
j--;
}
}
//使用基准值填坑,这就是基准值的最终位置
arr[i] = x;//arr[j] = y;
//返回基准值的位置索引
return i; //return j;
}
private static void quickSort(int[] arr, int low, int high)
{//???递归何时结束
if(low < high)
{
//分区操作,将一个数组分成两个分区,返回分区界限索引
int index = partition(arr,low,high);
//对左分区进行快排
quickSort(arr,low,index-1);
//对右分区进行快排
quickSort(arr,index+1,high);
}
}
public static void quickSort(int[] arr)
{
int low = 0;
int high = arr.length-1;
quickSort(arr,low,high);
}
public static void main(String[] args)
{
//给出无序数组
int arr[] = {72,6,57,88,60,42,83,73,48,85};
//输出无序数组
System.out.println(Arrays.toString(arr));
//快速排序
quickSort(arr);
//partition(arr,0,arr.length-1);
//输出有序数组
System.out.println(Arrays.toString(arr));
}
}