简介
快速排序的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
简单来说就是:
1、取一个基准数,进行一次快速排序(执行一次方法),把所有小于它的数放左边,所有大于它的数放右边。
2、左半部分递归(进行第1步),右半部分递归(进行第1步)。
3、直到整个数组都有序。
举个例子:
我们要对 [3,5,1,2,4] 排序。
1、把 [3,5,1,2,4] 这一部分进行快速排序(执行一次方法)。
2、一路下来,得到数组 [2,1,3,5,4](3左侧的数都小于3,右侧数都大于等于3)
3、把左侧的 [2,1] 和右侧的 [5,4] 两个部分分别进行快速排序(分别执行一次方法)
4、分别得到 [1,2] 和 [4,5]
5、排序完毕,得到 [1,2,3,4,5]
思路
1、写两个方法,一个是getIndex(int[] arr, int left, int right), 一个是quickSort(int[] arr, int left, int right)。
2、getIndex(int[] arr, int left, int right) 方法:
public static int getIndex(int[] arr, int left, int right)
{
//基准数是该区域[left, right]的第一个数
int temp = arr[left]; //【此时left的位置是空出来的】
while(left < right)
{
//先从right开始判断, 如果大于等于temp就不管他,right自减;如果小于temp就(跳出循环)和left位置交换
while(left < right && arr[right] >= temp)
{
right --;
}
arr[left] = arr[right]; //【此时right的位置是空出来的】
//随后从left开始判断,如果小于temp就不管他,如果大于temp就和right位置交换
while(left < right && arr[left] <= temp)
{
left ++;
}
arr[right] = arr[left]; //【此时left的位置是空出来的】
}
//退出了循环,说明left==right,此时left\right就是基准数temp应该放的位置
arr[left] = temp; //【填补空出来的位置】
return left;
}
(1)在 [left, right] 区域内,定义基准数temp = arr[left](也就是区域的第一个数)。
[ {3},5,1,2,[4] ], left = 0,right = 4,temp = 3;
(2)先从该区域的末尾开始扫描,如果有小于3的数,把它和 left 位置交换(注意:可以直接忽视3这个元素,因为它已经存到了temp 变量里了)。
[ {3},5,1,2,[4] ], left = 0,right = 4,temp = 3,4 > 3成立,right减1
[ {3},5,1,[2],4 ], left = 0,right = 3,temp = 3,2 > 3不成立, 交换:
[ {2},5,1,[3],4 ], left = 0,right = 3,temp = 3
(3)然后从该区域的起点开始扫描,如果有大于3的数,把它和right 位置交换
[ {2},5,1,[3],4 ], left = 0,right = 3,temp = 3,2 < 3成立,left加1
[ 2,{5},1,[3],4 ], left = 1,right = 3,temp = 3,5 < 3不成立,交换:
[ 2,{3},1,[5],4 ], left = 1,right = 3,temp = 3
(4)重复第(2)步。
[ 2,{3},1,[5],4 ], left = 1,right = 3,temp = 3,5>3成立,right减1
[ 2,{3},[1],5,4 ], left = 1,right = 2,temp = 3,1>3不成立,交换:
[ 2,{1},[3],5,4 ], left = 1,right = 2,temp = 3
(5)重复第(3)步。
[ 2,{1},[3],5,4 ], left = 1,right = 2,temp = 3,1<3成立,left加1
[ 2,1,{[3]},5,4 ], left = 2,right = 2,temp = 3
(6)当left = right时,退出以上循环,left \ right 的位置就是基准数temp应该放的位置。返回这个位置的值。
arr[left] = temp;
return left;
2、quickSort(int[] arr, int left, int right) 方法:
public static void quickSort(int[] arr, int left, int right)
{
if(left < right)
{
int mid = getIndex(arr, left, right);
//左侧区域递归
quickSort(arr, left, mid - 1);
//右侧区域递归
quickSort(arr, mid + 1, right);
}
}
完整代码
public class ALGO_234
{
public static int getIndex(int[] arr, int left, int right)
{
//基准数是该区域[left, right]的第一个数
int temp = arr[left]; //【此时left的位置是空出来的】
while(left < right)
{
//先从right开始判断, 如果大于等于temp就不管他,right自减;如果小于temp就(跳出循环)和left位置交换
while(left < right && arr[right] >= temp)
{
right --;
}
arr[left] = arr[right]; //【此时right的位置是空出来的】
//随后从left开始判断,如果小于temp就不管他,如果大于temp就和right位置交换
while(left < right && arr[left] <= temp)
{
left ++;
}
arr[right] = arr[left]; //【此时left的位置是空出来的】
}
//退出了循环,说明left==right,此时left\right就是基准数temp应该放的位置
arr[left] = temp; //【填补空出来的位置】
return left;
}
public static void quickSort(int[] arr, int left, int right)
{
if(left < right)
{
int mid = getIndex(arr, left, right);
//左侧递归
quickSort(arr, left, mid - 1);
//右侧递归
quickSort(arr, mid + 1, right);
}
}
public static void main(String[] args)
{
// Scanner sc = new Scanner(System.in);
// String s = sc.nextLine();
// char[] str = s.toCharArray();
int[] arr = {3, 4, 1, 2, 5};
quickSort(arr, 0, arr.length - 1);
for(int i = 0; i < arr.length; i++)
System.out.print(arr[i] + " ");
}
}
输出结果:
1 2 3 4 5