快速排序

左心房为你撑大大i 提交于 2020-01-10 02:25:23

排序算法采用了一种分治的策略,即将大模块划分成同样的小模块。

快排的基本思想:

  1. 先从数组中取出一个数作为基准数,通常取数组的第一个元素作为基准数
  2. 分区过程,将比基准数大的数放到他的右边,小于或等于他的数放到左边
  3. 经过一次分区后,便可以将原数组分成基准数的左边都小于等于基准数,而右边都大于基准数的数组。重复第2步的过程,直到区间只有一个数,最终就可以得到一个有序的数组

快速排序实际上就是挖坑+填数+分治的过程。

以一个数组arr为例,取第一个数作为基准数

0

1

2

3

4

5

6

7

8

9

72

6

55

80

60

90

42

73

48

100

初始时 i=0,j=5,x=arr[0]。

由于已经将arr[0]保存到x了,所以arr[0]可以被其他数填充了,相当于在arr[0]上挖了个坑。

j从右向左遍历数组,找第一个小于等于x的数,在j=8的位置满足要求,将arr[8]挖出填到arr[0]中,同时i++,此时arr[8]多出一个坑位,等待其他数填充。i从左向右遍历,找到第一个比x大的数,i=3符合要求,将arr[3]的数取出填到arr[8]中,同时j--,数组变为

0

1

2

3

4

5

6

7

8

9

48

6

55

80

60

90

42

73

80

100

此时i=3,j=7,x=72;

再重复上面的步骤,先从后向前找,再从前向后找。

从j开始向前找,j=6,符合条件,arr[6]挖出一个坑填到arr[3]上,arr[3]=arr[6];i++

从i开始向后找,i=5,符合条件,arr[5]挖坑填到arr[6]上,arr[6]=arr[5];j--;

0

1

2

3

4

5

6

7

8

9

48

6

55

42

60

90

90

73

80

100

此时i==j=5,将arr[5]用x填上,即arr[5]=x;

数组变为:

0

1

2

3

4

5

6

7

8

9

48

6

55

42

60

72

90

73

80

100

可以看出arr[5]左边的数都小于等于arr[5],arr[5]右边的数都大于他

对arr[5]左边和右边的两个子数组递归实现上述过程,最终可以得到一个有序的数组。

对挖坑填数进行总结:

  1. i=L,j=R,将基准数挖出,形成第一个坑arr[i]
  2. 由后向前找第一个小于等于基准数的数arr[j],找到后挖出此数形成第二个坑arr[j],arr[i]=arr[j];
  3. 由前向后找第一个大于基准数的数arr[i],找到后挖出此数形成新坑arr[i],arr[j]=arr[i];
  4. 重复执行第2、3步,直到i==j,填坑arr[i]=基准数
  5. 分别对arr[i]的左右两边递归调用,从而达到数组有序的目的

代码实现如下:

package com.atguigu.sort;

import java.util.Arrays;

public class QuickSort {

	public static void main(String[] args) {
		int[] arr= {72,6,55,80,60,90,42,73,48,100};
		quickSort(arr, 0, arr.length-1);
		System.out.println(Arrays.toString(arr));
	}
	
	public static void quickSort(int[] arr,int low,int high) {
		int X=arr[low];//挖坑
		int i=low;
		int j=high;
		if(low<high) {//递归结束的条件
			while(i<j) {
				while(i<j&&arr[j]>X) {//从右向左找小于于等于X的数
					j--;
				}
				if(i<j) {
					arr[i++]=arr[j];//arr[i]处填坑,arr[j]形成了新坑
				}
				while(i<j&&arr[i]<=X) {//从左向右找大于X的数
					i++;
				}
				if(i<j) {
					arr[j++]=arr[i];//arr[j]处填坑,arr[i]形成了新坑
				}
			}
			//i==j处结束循环
			arr[i]=X;//arr[i]处填坑
			
			//分治
			quickSort(arr, low, i-1);//在arr[i]的左边递归调用
			quickSort(arr, i+1, high);//在arr[i]的右边递归调用
		}
	}

}

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!