【杂谈】分治思想与快速排序

基本思想

所谓”分治“,顾名思义——”分而治之“,即是在处理一个复杂问题时,将其分化成多个简单问题,分别求解,以求出原问题的解
用式子表示为:

f(n) = f(1/n)+f(1/n)+……+f(1/n)


快速排序

在此以快速排序为例对分治策略进行解析。
快排的思想简单的来说,即是选取一个标准数,使得序列中的其他数按照与标准数的大小关系排列在其两侧,然后在其两侧重复这个过程,直到当次序列中只有被选取的标准数为止,完成排序,换而言之,即是一种分治策略,将复杂问题分化成n个简单小问题。
例如,有如下一组无序数列,将其进行升序排序:

58 23 78 69 12 36 46

首先我们选取出一个标准数,这里不对选取标准数的方法做过多讨论,此处我们采取选取数列中第一个数为标准数的方法,那么将其与序列中的最后一个数进行比较:

58 > 46

但是46在标准数的右边,故将标准数与该数互换位置,得到序列为:

46 23 78 69 12 36 58

再继续比较,比较位向标准数位置前进一步,将标准数与该数(23)进行比较:

23 < 58

且23已在标准数(58)的左边,故不发生变化,比较位继续推进,得到下一组比较:

78 > 58

但是78在标准数的左边,故互换位置,得到新序列:

46 23 58 69 12 36 78

下一步:

58 > 36
46 23 36 69 12 58 78

再下一步:

69 > 58
46 23 36 58 12 69 78

接着再一步:

58 > 12
46 23 36 12 58 69 78

再往下进行一步后,我们得到比较位与标准数在同一位置了,故此次比较结束,此时得到的序列中,标准数左边的数全都小于它,在其左边的数全都大于它,初次的排序完成了,这里得到了在最终排序结果中的标准数的正确位置,让我们进行一次分治对标准数左右两边的序列:

46 23 36 12
69 78

同样地重复这个过程,如此循环往复的进行分治,直到分出的序列中只有一个数为止,此时得到的,便是最终的升序序列了:

12 23 36 46 58 69 78


代码

这里给出Java的实现代码:


public class Main {
	
	public static void main(String[] args) {
		int a[] = {58,23,78,69,12,36,46};//无序数组
		q_sort(a,0,a.length-1);
		for(int i = 0;i < a.length;i++)System.out.print(a[i]+" ");//输出该数组查看结果
		System.out.println();
	}

//	创建快速排序方法,视 'i'为标准数,i与j为当次分治的起始位置与结束位置
	static void q_sort(int[] a,int i,int j) {
		if(i == j || i >= a.length || j >= a.length || i < 0 ||j < 0||i > j)return;//当次序列中只剩下一个元素时或者i,j不合法时结束分治
		int q = i,e = j;//记录序列的位置
		while(i != j){
			if((a[i] > a[j] && i < j) || (a[i] < a[j] && i > j)){
				a[i] = a[i] ^ a[j];
				a[j] = a[i] ^ a[j];
				a[i] = a[i] ^ a[j];
				
				i = i ^ j;
				j = i ^j;
				i = i ^ j;
			}
			j = j < i?++j:--j;
		}
		q_sort(a,q,i-1);//对标准数左序列进行分治
		q_sort(a,i+1,e);//对标准数右序列进行分治
	}
	
}


猜你喜欢

转载自blog.csdn.net/Jourofant/article/details/107495853