快速排序的简单实现

快速排序的基础思想就是分而治之,通过选择主元将数组分成两段,依次将比主元小的数放在主元左边,比主元大的数放主元右边,当一次主元比较结束时,主元所在的位置就是它的最终位置。如下图,然后递归调用。
在这里插入图片描述

什么时候是快速排序的最好情况?

每次正好中分 ——> T(N)=O(N logN)

怎么样选主元是很重要的:

这里我们取头、中、尾三数的中位数来做主元;
需要注意的是,当我们取到主元后,将主元与数组的最后一个元素换位置,这样以便于我们接下来的比较。

子集划分

在这里插入图片描述如上图,我们将主元放在数组末尾,设置两个指针(i=0,j=length-1):
i所指的元素从起始位置依次与主元比较,当比主元小时指针往后移,否则停下来等;
j所指的元素从起始位置依次与主元比较,当比主元大时指针往前移,否则停下来等;
当两个指针都停下时,交换他们所指的元素。
注意:当所指的元素与主元相等时,应该停下来(考虑其效率)。

什么时候指针停下来呢?
当i - j大于等于0 时,将主元与i指针所指的元素换位置(此时正好是主元的最终位置)
在这里插入图片描述
然后递归调用该方法。

代码实现如下:

public class Quicksort {
	public int pivot(int[] array, int left, int right) {
		int mid = (left + right) / 2;
		if (array[left] > array[mid]) {
			swap(array, left, mid);
		}
		if (array[left] > array[right]) {
			swap(array, left, right);
		}
		if (array[mid] > array[right]) {
			swap(array, mid, right);
		}
		swap(array, mid, right);//将主元放到最右边
		int tamp = array[right];
		return tamp;
	}

	public void quickSort(int a[]) {
		int start = 0;
		int end = a.length - 1;
		quicksort(a, start, end);
	}

	public void swap(int array[], int i, int j) {
		int a = array[i];
		int b = array[j];
		array[i] = b;
		array[j] = a;
	}

	public void quicksort(int[] array, int left, int right) {
		if (left >= right) {
			return;
		}
		int temp = pivot(array, left, right);

		int i = left;
		int j = right - 1;

		while (i < j) {
		//当此时元素大于主元时停下来做交换
		//当i 和 j相等时(i和j所指的是同一个位置)且符合往前的条件 i 应该继续往前走
			while (array[i] <= temp && i <= j) {
				i++;
			}
			while (array[j] >= temp && i < j) {
				j--;
			}
			if (i < j) {
				swap(array, i, j);
			} else
				break;
		}
		swap(array, i, right);//将主元放到正确的位置

		quicksort(array, left, i - 1);//递归
		quicksort(array, i + 1, right);
	}

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		int[] array = { 12, 20, 5, 16,12,12, 15, 1, 30, 45, 23, 9 };

		Quicksort test = new Quicksort();
		test.quickSort(array);
		for (int i : array) {
			System.out.print(i + " ");
		}
	}
}

快速排序的问题

当小规模数据(例如N不到100)排序时,可能还不如用简单排序快(例如插入排序等)。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值