【基础算法】排序-复杂排序之二(快速排序)

归并排序在时间复杂度上大大的优化了,但是出现了一个问题,就是额外线性空间的使用。因为在归并排序的过程中,sub1数组和sub2数组只能保证一个元素排到正确的位置,另一个不能保证,所以必须用额外的空间来保存这个元素。

那么有没有一种方法,它能够保证在分割的情况下,交换两个元素的时候,元素就能排到正确的位置上呢?因为这样就不需要额外的数组空间了。于是科学家发明了快速排序。

快速排序的基本思想是基于分割,与归并排序不同在于,它的分割方式不是等份分割,而是随机选取分割元素,然后通过交换的方式保证分割点前面的元素比它小,分割点后面的元素比它大。这下递归下去就能保证每个元素都交换到自己的位置上了。

前面我们提到了随机选取分割的元素,所以一般情况下我们会选择首个元素作为分割元素。

那么如何选择交换的元素呢?当然是双指针大法:定义两个指针i,j。i指向除掉分割元素的第一个元素,j指向最后一个元素。如果A[i]<partition, 说明i这个位置满足分割的要求,i++就可以了,同理,如果A[j]>partition, 那么说明j也满足位置分割的要求,j--就可以了。

所以选择交换的两个元素即A[i]不满足A[i]<partition和A[j]不满足A[j]>partition。这个时候交换i个j即可。

什么时候结束分割呢?

当i>=j的时候就可以结束了,这个时候j的位置正好比partition小,而i的位置正好比partition大,交换partition和j就可以了。

		while (true) {

			while (more(array[left], array[++i]))
				if (i == right)
					break;
			while (more(array[--j], array[left]))
				if (j == left)
					break;

			if (i >= j)
				break;
			exchange(array, i, j);
		}

记住这里一定是i>=j就要跳出,因为当i==j的时候,i和j指向的那个元素一定小于partition且是最后一个元素。如果不跳出的话,数组会出现越界

当i>j的时候,i指向的元素一定比partition大,j指向的元素一定比partition小。

边界条件非常重要。

接下来是分割部分,其实挺简单,就是分成partition, left and right三部分就可以了

	public static void quickSort(int[] array, int left, int right) {
		if (left >= right)
			return;
		int partitionIndex = partition(array, left, right);
		quickSort(array, left, partitionIndex - 1);
		quickSort(array, partitionIndex + 1, right);
	}

快速排序的时间复杂度为O(NlogN)

证明如下


快速排序是一种非常经典的排序,速度比归并排序有明显的提升。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值