快速排序算法(java实现)

快速排序是一种高效的内部排序方法,平均时间复杂度为O(nlog2n),但最坏情况下为O(n^2)。它通过设定分界值,不断划分数组,最终实现排序。在实际应用中,可以通过‘三者值取中’策略优化选取中间数的过程,以及在序列长度较小时切换到插入排序,以提高效率。此外,快速排序在递归过程中可能需要较多的栈空间,空间复杂度为O(log2n)。
摘要由CSDN通过智能技术生成

快速排序(Quicksort)是对冒泡排序算法的一种改进。

复杂度:

  • O(nlog2 n)

是否稳定:

  • 快速排序不是一种稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动。

适用场景:

  • 当数据量较大,要求速度较快的时候可以使用(比较的元素越多,快速排序比冒泡排序越快)
  • 当输入的数据基本有序的时候
  • 数据量小时不建议用

优化:

  1. 序列长度达到一定大小时,使用插入排序
  2. 尾递归优化
  3. 聚集元素
  4. 多线程处理快排

快速排序算法通过多次比较和交换来实现排序,其排序流程如下:

1. 首先设定一个分界值,通过该分界值将数组分成左右两部分。
2. 将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。此时,左边部分中各元素都小于或等于分界值,而右边部分中各元素都大于或等于分界值。
3. 然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理。 
4. 重复上述过程,可以看出,这是一个递归定义。通过递归将左侧部分排好序后,再递归排好右侧部分的顺序。当左、右两个部分各数据排序完成后,整个数组的排序也就完成了。

在这里插入图片描述

public static void quickSort(int[] arr,int low,int high){
	//sentry哨兵
    int i=low,j=high,sentry,temp;
    if(low>high)
         return;
    sentry=arr[low];
    while(i<j){
         while(sentry<=arr[j] && i<j){
            j--;
         }
         while ((sentry >= arr[i] && i < j)) {
            i++;
         }
         if(i<j){
            temp = arr[i];
            arr[i] = arr[j];
            arr[j] =temp;
        }
    }
    arr[low] = arr[i];
    arr[i] = sentry;
    quickSort(arr,low,j-1);
	quickSort(arr,j+1,high);
}

输出结果为
在这里插入图片描述

理想的情况是,每次划分所选择的中间数恰好将当前序列几乎等分,经过log2n趟划分,便可得到长度为1的子表。这样,整个算法的时间复杂度为O(nlog2 n)。

最坏的情况是,每次所选的中间数是当前序列中的最大或最小元素,这使得每次划分所得的子表中一个为空表,另一子表的长度为原表的长度-1。这样,长度为n的数据表的快速排序需要经过n趟划分,使得整个排序算法的时间复杂度为O(n^2)。

为改善最坏情况下的时间性能,可采用其他方法选取中间数。通常采用“三者值取中”方法,即比较H->r[low].key、H->r[high].key与H->r[(low+high)/2].key,取三者中关键字为中值的元素为中间数。

可以证明,快速排序的平均时间复杂度也是O(nlog2 n)。因此,该排序方法被认为是目前最好的一种内部排序方法。

从空间性能上看,尽管快速排序只需要一个元素的辅助空间,但快速排序需要一个栈空间来实现递归。最好的情况下,即快速排序的每一趟排序都将元素序列均匀地分割成长度相近的两个子表,所需栈的最大深度为log2(n+1);但最坏的情况下,栈的最大深度为n。这样,快速排序的空间复杂度为O(log2 n)。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值