龙空技术网

看动图学算法(六):快速排序的原理和Java讲解

Code404 58

前言:

眼前同学们对“算法复杂度为onlogn的排序方法”都比较注重,同学们都需要分析一些“算法复杂度为onlogn的排序方法”的相关内容。那么小编在网络上搜集了一些关于“算法复杂度为onlogn的排序方法””的相关文章,希望我们能喜欢,咱们快快来学习一下吧!

快速排序(Quick Sort)是一种常用的排序算法,它的时间复杂度为O(nlogn),是在平均情况下具有良好性能的排序算法之一。

一、原理

快速排序算法采用了分治的思想,将一个大问题分解成若干个小问题来解决。其基本思路是选取一个基准元素,将数组分成两个子序列,其中一个子序列的所有元素都小于基准元素,另一个子序列的所有元素都大于或等于基准元素。然后再对这两个子序列进行递归操作,直到所有序列长度为1时排序完成。

快速排序的平均时间复杂度为O(nlogn),最坏情况下的时间复杂度为O(n^2),其中n为待排序的元素个数。快速排序对于大规模数据的排序效率比较高,是常用排序算法之一。

二、快速排序算法实现过程

快速排序的实现需要完成以下几步:

选择序列中的一个元素作为基准值(pivot),通常选择首个元素或末尾元素作为基准值;将低于基准元素的放到左边,高于或等于基准元素的放到右边。对基准值左右两侧的子序列分别重复上述步骤,直到所有元素均被排完序为止。

2.1 选择基准元素

选择基准元素是快速排序的第一步,其目的是将待排序数组分成两个子序列。最常用的方法是选取第一个元素作为基准元素。但是,如果待排序数组已经有序或近乎有序,那么选取第一个元素就会导致快速排序的时间复杂度变为O(n^2)。为了解决这个问题,可以采用随机化的方法来选择基准元素。

以下是选取第一个元素作为基准元素的代码实现:

public static int partition(int[] arr, int low, int high) {    int pivot = arr[low]; //基准元素    while (low < high) {        while (low < high && arr[high] >= pivot) {            high--;        }        arr[low] = arr[high]; //将比基准元素小的移到低端        while (low < high && arr[low] <= pivot) {            low++;        }        arr[high] = arr[low]; //将比基准元素大的移到高端    }    arr[low] = pivot; //把基准元素放到最终位置    return low;}

以下是采用随机化方法选择基准元素的代码实现:

public static int partition(int[] arr, int low, int high) {    int randomIndex = (int) (Math.random() * (high - low + 1)) + low; //随机选取一个位置    swap(arr, randomIndex, high); //交换基准元素和随机元素    int pivot = arr[high]; //基准元素    while (low < high) {        while (low < high && arr[low] <= pivot) {            low++;        }        arr[high] = arr[low]; //将比基准元素大的移到高端        while (low < high && arr[high] >= pivot) {            high--;        }        arr[low] = arr[high]; //将比基准元素小的移到低端    }    arr[high] = pivot; //把基准元素放到最终位置    return high;}private static void swap(int[] arr, int i, int j) {    int temp = arr[i];    arr[i] = arr[j];    arr[j] = temp;}
2.2 将低于基准元素的放到左边,高于或等于基准元素的放到右边

这一步是快速排序的关键步骤,其代码实现如下:

public static void quickSort(int[] arr, int low, int high) {    if (low < high) {        int pivotIndex = partition(arr, low, high);        quickSort(arr, low, pivotIndex - 1); //递归排序左半部分        quickSort(arr, pivotIndex + 1, high); //递归排序右半部分    }}

2.3 对基准值左右两侧的子序列分别重复上述步骤,直到所有元素均被排完序为止。

这一步是快速排序的递归过程,其代码实现如上文所示。

三、示例代码

下面是使用Java语言实现快速排序的示例代码:

import java.util.Arrays;public class QuickSort {    public static void main(String[] args) {        int[] arr = {32, 6, 17, 28, 10, 22, 43, 13, 48, 35};        System.out.println("Before sorting: " + Arrays.toString(arr));        quickSort(arr, 0, arr.length - 1);        System.out.println("After sorting: " + Arrays.toString(arr));    }    public static void quickSort(int[] arr, int low, int high) {        if (low < high) {            int pivotIndex = partition(arr, low, high);            quickSort(arr, low, pivotIndex - 1); //递归排序左半部分            quickSort(arr, pivotIndex + 1, high); //递归排序右半部分        }    }    public static int partition(int[] arr, int low, int high) {        int randomIndex = (int) (Math.random() * (high - low + 1)) + low; //随机选取一个位置        swap(arr, randomIndex, high); //交换基准元素和随机元素        int pivot = arr[high]; //基准元素        while (low < high) {            while (low < high && arr[low] <= pivot) {                low++;            }            arr[high] = arr[low]; //将比基准元素大的移到高端            while (low < high && arr[high] >= pivot) {                high--;            }            arr[low] = arr[high]; //将比基准元素小的移到低端        }        arr[high] = pivot; //把基准元素放到最终位置        return high;    }    private static void swap(int[] arr, int i, int j) {        int temp = arr[i];        arr[i] = arr[j];        arr[j] = temp;    }}
四、动图效果演示

快速排序算法演示,若动图显示失败请刷新重试

上面的动图效果的步骤,首先基准值取第一个元素32,然后逐一比较,把小于基准值的移到左侧,大于基准值的移到右侧。整个数组拆分成了P1、P2两个数组

接着对左侧的P1数组进行快速排序,基准值取第一个元素13,那么P1数组又被拆分成更小的左右两个数组P3、P4。

继续对上面拆分出来的P3数组快速排序,基准值取第一个元素10

左侧数组的长度已经是1,排序已经完成,开始对13的右边P4数组快速排序,基准值取第一个元素28,P4中没有比基准值28大的数字,所以只有左侧的P5数组

接着是28的左侧P5数组快速排序,基准值取第一个元素22,

结果数组长度已经是1,结束。

接着对32的右侧部分P2数组快速排序,基准值取第一个元素43

到这里,所有最小单位的数组都已经拆成了长度为1的数组,无法继续拆分,快速排序结束得到了最终的结果。

标签: #算法复杂度为onlogn的排序方法 #java快速排序算法的原理 #java排序原理