快速排序

来源:互联网 发布:网络咨询医生有前途吗 编辑:程序博客网 时间:2024/06/06 12:57

相对冒泡排序、选择排序等算法而言,快速排序的具体算法原理及实现有一定的难度。为了更好地理解快速排序,我们仍然以举例说明的形式来详细描述快速排序的算法原理。在前面的排序算法中,我们以5名运动员的身高排序问题为例进行讲解,为了更好地体现快速排序的特点,这里我们再额外添加3名运动员。实例中的8名运动员及其身高信息详细如下(F、G、H为新增的运动员): A(181)、B(169)、C(187)、D(172)、E(163)、F(191)、G(189)、H(182)

在前面的排序算法中,这些排序都是由教练主导完成了,现在运动员人数增加了,教练也想趁机去休息一下,于是教练叫来了两名助手,让这两名助手以快速排序法的排序方式来实现对8名运动员的身高从左到右、从低到高的排序。

按照快速排序法的算法原理,两名助手分别站在运动员排列的两侧,如下图所示:

201654161611529.png (587×80)

首先,助手1从排列中选出一名运动员(一般选择左侧第1位运动员或最中间的运动员),这里选择运动员A(181)。由于排序是从左到右、从低到高,所以助手1需要一个身高比A(181)更小的运动员(选出来的A(181)作为比较的基准,本轮所有的比较,都是与最初选出来的运动员A(181)比较):

201654161640234.png (665×171)

201654161656734.png (639×142)

201654161713046.png (646×151)

201654161739235.png (639×152)

201654161755999.png (625×147)


201654161810165.png (650×138)

201654161825241.png (640×135)

201654161844120.png (688×131)

当两名助手在排序寻找的过程中相遇后,就停止当前轮次的比较,并把最初选出来的运动员A(181)放在两名助手相遇的空位上:

201654161859313.png (633×82)

在快速排序中,当两名助手相遇时,本轮排序就结束了。此时,我们发现,以两名运动员相遇的位置A(181)作为分割点,排列左边的都是身高比A(181)小的运动员,排列右侧的都是身高比A(181)大的运动员。这个时候,我们再把A(181)左侧和右侧的两个排序分开来看,如果我们继续使用上述两名助手的排序方法分别对两边的排列进行排序,那么经过多次排列后,最后就能够得到我们所需要的排序结果。

上面就是快速排序的整个排序实现过程。快速排序就是利用上述的排序规则,将一个排列分为两个排列,两个排列分为四个排列,直到无排列可分为止,最后就得到了我们所需要的排序结果。

现在,我们依然编程Java代码来实现使用快速排序对上述8名运动员的身高进行排序:

public static final void quickSort(int[] array, int start, int end) {  // i相当于助手1的位置,j相当于助手2的位置  int i = start, j = end;  int pivot = array[i]; // 取第1个元素为基准元素  int emptyIndex = i; // 表示空位的位置索引,默认为被取出的基准元素的位置  // 如果需要排序的元素个数不止1个,就进入快速排序(只要i和j不同,就表明至少有2个数组元素需要排序)  while (i < j) {    // 助手2开始从右向左一个个地查找小于基准元素的元素    while (i < j && pivot <= array[j])      j--;    if (i < j) {      // 如果助手2在遇到助手1之前就找到了对应的元素,就将该元素给助手1的"空位",j成了空位      array[emptyIndex] = array[emptyIndex = j];    }         // 助手1开始从左向右一个个地查找大于基准元素的元素    while (i < j && array[i] <= pivot)      i++;    if (i < j) {      // 如果助手1在遇到助手2之前就找到了对应的元素,就将该元素给助手2的"空位",i成了空位      array[emptyIndex] = array[emptyIndex = i];    }  }      // 助手1和助手2相遇后会停止循环,将最初取出的基准值给最后的空位  array[emptyIndex] = pivot;     // =====本轮快速排序完成=====     // 如果分割点i左侧有2个以上的元素,递归调用继续对其进行快速排序  if (i - start > 1) {    quickSort(array, 0, i - 1);  }  // 如果分割点j右侧有2个以上的元素,递归调用继续对其进行快速排序  if (end - j > 1) {    quickSort(array, j + 1, end);  }} //主方法public static void main(String[] args) {  // =====使用快速排序法对表示8名运动员身高的数组heights进行从低到高的排序=====  // A(181)、B(169)、C(187)、D(172)、E(163)、F(191)、G(189)、H(182)  int[] heights = { 181, 169, 187, 172, 163, 191, 189, 182 };  // 调用快速排序方法  quickSort(heights, 0, heights.length - 1);  // 输出排序后的结果  for (int height : heights) {    System.out.println(height);  }}
以上Java代码运行结果输出如下:
163169172181182187189191



原创粉丝点击