【algorithm】java实现快速排序

算法,根据设计方法来分类,可以分为穷举法、分治法、线性规划法、动态规划法、贪心算法、回溯法等。


快速排序采用分治法,原理如下:

快速排序是对冒泡排序的一种改进。它的基本思想是:通过一躺排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一不部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
     假设要排序的数组是A[1]……A[N],首先任意选取一个数据(通常选用第一个数据)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一躺快速排序。一躺快速排序的算法是:
    1)、设置两个变量I、J,排序开始的时候I:=1,J:=N;
    2)以第一个数组元素作为关键数据,赋值给X,即X:=A[1];
    3)、从J开始向前搜索,即由后开始向前搜索(J:=J-1),找到第一个小于X的值,两者交换;
    4)、从I开始向后搜索,即由前开始向后搜索(I:=I+1),找到第一个大于X的值,两者交换;
    5)、重复第3、4步,直到I=J;
    例如:待排序的数组A的值分别是:(初始关键数据X:=49)
                 A[1]      A[2]      A[3]      A[4]      A[5]       A[6]      A[7]: 
                  49         38        65        97        76        13         27
第一次交换后:    27         38        65        97        76        13         49
( 按照算法的第三步从后面开始找)
第二次交换后:    27         38        49        97        76        13         65
( 按照算法的第四步从前面开始找>X的值,65>49,两者交换,此时I:=3 )
第三次交换后:    27         38        13        97        76        49         65
( 按照算法的第五步将又一次执行算法的第三步从后开始找)
第四次交换后:    27         38        13        49        76        97         65
( 按照算法的第四步从前面开始找大于X的值,97>49,两者交换,此时J:=4 )
此时再执行第三步的时候就发现I=J,从而结束一躺快速排序,那么经过一躺快速排序之后的结果是:27    38    13    49    76    97    65,即所以大于49的数全部在49的后面,所以小于49的数全部在49的前面。
       快速排序就是递归调用此过程--再以49为中点分割这个数据序列,分别对前面一部分和后面一部分进行类似的快速排序,从而完成全部数据序列的快速排序,最后把此数据序列变成一个有序的序列。
1)、设有N(假设N=10)个数,存放在S数组中;
2)、在S[1。。N]中任取一个元素作为比较基准,例如取T=S[1],起目的就是在定出T应在排序结果中的位置K,这个K的位置在:S[1。。K-1]<=S[K]<=S[K+1..N],即在S[K]以前的数都小于S[K],在S[K]以后的数都大于S[K];
3)、利用分治思想(即大化小的策略)可进一步对S[1...K-1]和S[K+1...N]两组数据再进行快速排序直到分组对象只有一个数据为止。

文字太辛苦,看看图:



之前只是进行到这一步,真动手写代码,发现,弱爆了。


……………………


…………


还是写写吧,源码如下:

package dec;

/**
 * 
 * 
 * <p>
 * Title: 快速排序示例代码 /p>
 * 
 * <p>
 * Description: 示例 业务类
 * </p>
 * 
 * <p>
 * Copyright: Copyright (c) 2012
 * </p>
 * 
 * 
 * @author dml@2012-12-6
 * @version 1.0
 */

public class QSort {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		quicksort qs = new quicksort();
		int data[] = { 14, 23, 2, 32, 54, 32, 58, 79, 39, 11 };
		qs.data = data;
		qs.sort(0, qs.data.length - 1);
		qs.display();
	}

}

class quicksort {
	public int data[];

	private int partition(int sortArray[], int low, int high) {
		int key = sortArray[low];

		while (low < high) {
			while (low < high && sortArray[high] >= key)
				high--;
			sortArray[low] = sortArray[high];

			while (low < high && sortArray[low] <= key)
				low++;
			sortArray[high] = sortArray[low];
		}
		sortArray[low] = key;
		return low;
	}

	public void sort(int low, int high) {
		if (low < high) {
			int result = partition(data, low, high);
			sort(low, result - 1);
			sort(result + 1, high);
		}

	}

	public void display() {
		for (int i = 0; i < data.length; i++) {
			System.out.print(data[i]);
			System.out.print(" ");
		}
	}
}

要真这么写就提交了,肯定被骂死,按照步骤来,先写抽象类:

package dec;

/**
 * 
 * 
 * <p>Title: 快速排序 /p>
 *
 * <p>Description: 示例 业务类</p>
 *
 * <p>Copyright: Copyright (c) 2012</p>
 *
 *
 * @author dml@2012-12-6
 * @version 1.0
 */
public abstract class QuickSort {
	protected abstract int partition(int sortArray[], int low, int high);
	public abstract void sort(int low, int high);
	public abstract void display();
}

既然是分治法,关键的方法就是怎么分,怎么处理,这个写清楚了,基本也就搞清楚这个算法的实现过程了。


实现类如下:

package dec;

/**
 * 
 * 
 * <p>
 * Title: 快速排序实现类 /p>
 * 
 * <p>
 * Description: 示例 业务类
 * </p>
 * 
 * <p>
 * Copyright: Copyright (c) 2012
 * </p>
 * 
 * 
 * @author dml@2012-12-6
 * @version 1.0
 */
public class QuickSortImpl extends QuickSort {
	public int data[];

	/*
	 * (non-Javadoc)
	 * 
	 * @see dec.QuickSort#partition(int[], int, int)
	 */
	@Override
	protected int partition(int[] sortArray, int low, int high) {
		int key = sortArray[low];

		while (low < high) {
			while (low < high && sortArray[high] >= key)
				high--;
			sortArray[low] = sortArray[high];

			while (low < high && sortArray[low] <= key)
				low++;
			sortArray[high] = sortArray[low];
		}
		sortArray[low] = key;
		return low;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see dec.QuickSort#sort(int, int)
	 */
	@Override
	public void sort(int low, int high) {
		if (low < high) {
			int result = partition(data, low, high);
			sort(low, result - 1);
			sort(result + 1, high);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see dec.QuickSort#display()
	 */
	@Override
	public void display() {
		for (int i = 0; i < data.length; i++) {
			System.out.print(data[i]);
			System.out.print(" ");
		}
	}

	public static void main(String[] args) {
		QuickSortImpl qs = new QuickSortImpl();
		int data[] = { 14, 23, 2, 32, 54, 32, 58, 79, 39, 11 };
		qs.data = data;
		qs.sort(0, qs.data.length - 1);
		qs.display();
	}

}

运行结果:

2 11 14 23 32 32 39 54 58 79 

验证无误,下来就是需要看时间复杂度了。这个等把其它各种排序都写完之后再汇总对比。


dml@wip 2012-12-6

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值