Java学习手册:(数据结构与算法-排序)快速排序

算法思想:

设两个指针i和j,它的初值分别为left和right。首先将基准记录r[left]移动至变量x中,使r[left]即r[i]相当于空单元,然后反复进行如下两个扫描过程,直至i和j相遇。

(1)j从右向左扫描,直到r[j]<x时,将人r[j]移至r[i],此时r[j]相当于空单元。

(2)i从左往右扫描,直到r[i]>x,将r[i]移至空单元r[j],此时r[i]相当于空单元。

当i和j相遇时,r[i](或r[j])相当于空单元,且r[i]的左边所记录的关键字均不大于基准记录的关键字,而r[i]右边所记录的关键字均不小于基准记录的关键字。

最后,将基准记录移至r[i]中,就完成了一次划分过程。

 

例子:举个栗子:对5,3,8,6,4这个无序序列进行快速排序,思路是右指针找比基准数小的,左指针找比基准数大的,交换之。
5,3,8,6,4 用5作为比较的基准,最终会把比5小的移动到5的左边,比5大的移动到5的右边。
5,3,8,6,4 首先设置i,j两个指针分别指向两端,j指针先扫描(思考一下为什么?)4比5小停止。然后i扫描,8比5大停止。交换i,j位置。
5,3,4,6,8 然后j指针再扫描,这时j扫描4时两指针相遇。停止。然后交换4和基准数。
4,3,5,6,8 一次划分后达到了左边比5小,右边比5大的目的。之后对左右子序列递归排序,最终得到有序序列。
上面留下来了一个问题为什么一定要j指针先动呢?首先这也不是绝对的,这取决于基准数的位置,因为在最后两个指针相遇的时候,要交换基准数到相遇的位置。一般选取第一个数作为基准数,那么就是在左边,所以最后相遇的数要和基准数交换,那么相遇的数一定要比基准数小。所以j指针先移动才能先找到比基准数小的数。
快速排序是不稳定的,其时间平均时间复杂度是O(nlgn)。

package com.haobi;
/*
 * 快速排序
 */
public class QuickSort {
	public static void sort(int[] array, int low, int high) {
		int i,j;
		int index;
		if(low>=high) {
			return;
		}
		i = low;//小指针
		j = high;//大指针
		index = array[i];//基准
		while(i<j) {//直至i,j相遇,跳出循环
			while(i<j&&array[j] >= index)//直至出现小于基准的数出现,跳出循环
				j--;//大指针左移
			if(i<j)
				array[i++] = array[j];//将该数存入基准中,该数变为新的基准
			while(i<j&&array[i]<index)//直至出现大于基准的数出现,跳出循环
				i++;//小指针大移
			if(i<j)
				array[j--] = array[i];//将该数存入基准中,该数变为新的基准
		}
		array[i] = index;//i,j相遇,基准记录存入array[i]中
		sort(array,low,i-1);//左边递归快排
		sort(array,i+1,high);//右边递归快排
	}
	public static void quickSort(int[] array) {
		sort(array,0,array.length-1);
	}
	public static void main(String[] args) {
		int[] array = {45,53,18,36,72,30,48,93,15};
		quickSort(array);
		for(int i=0;i<array.length;i++) {
			System.out.print(array[i]+" ");
		}
	}
}

程序输出结果如下:

15 18 30 36 45 48 53 72 93 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值