基于比较的快速排序-时间复杂度为O(nlogn)

快速排序

快排利用的是分治思想。如果要排序数组中下标从 p 到 r 之间的一组数据,选择p 到 r 之间的任意一个数据作为分区点pivot。

遍历 p 到 r 之间的数据,将小于pivot的放到左边,将大于pivot的放到右边,将pivot放到中间。经过这一步骤后数组 p 到 r 之间的数据就被分为了三个部分。数组 p 到 r 之间的数据就被分成了三个部分,前面 p
到 q-1 之间都是小于 pivot 的,中间是 pivot,后面的 q+1 到 r 之间是大于 pivot 的。再根据分治、递归的处理思想,可以用递归排序下标从p 到 q-1之间的数据和下标从q+1到 r 之间的数据,直到区间缩小为 1,就说明所有数据都有序了。
在这里插入图片描述

用递推公式将上面的过程写出来:

递推公式:
    quickSort(p…r) = quickSort(p…q-1) + quickSort(q+1, r)
终止条件:
    p >= r
实现方式

方法1: horea 法:

让 p 从前往后找,找比基准值大的元素,找到就停止
让 q 从后往前找,找比基准值小的元素,找到后停止
将 p 和 q 标记的元素进行交换(为了让前半部分小于后半部分,p 指的是小的)
将基准值和 p 位置的数据进行交换
返回 p
分割的时间复杂度:O(N)

    quickSort(int[] arr,int n) {
   
        quickSort_c(arr,0,n-1)
    }

    // 快速排序递归函数,p r为下标
    quick_sort_c(int[] arr,int p,int r) {
   

        if p >= r then return

        q = partition(arr, p, r) // 获取分区点的方法
      quick_sort_c(arr, p, q-1)
      quick_sort_c(arr, q+1, r)
	}

关于获取分区的方法,关键在于数据怎么划分,取哪个作为基准值

  • 取随机值,比如第一个或最后一个:
    每次取随机值数据划分存在极端情况:(递归的时间复杂度:递归的次数*每次递归的时间)
    如果每次基准值都可以将区间分割为左右均等的两部分 也是最优情况 O(nlogn)
    但是如果划分之后,数据都集中在区间的一侧,也就是数据比较有序 也是最差情况 O(n^2)

  • 优化:三数取中,使得取得的基准值刚好满足左右两边数据均匀

	public int getIndexOfMiddle(int[] arr,int p,int q) {
   
	    // 需要注意的是 p 和 right 是索引位置并且没有大小关系的
	    
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值