快速排序:源码(C++)--伪代码--时间复杂度解析

namespace htx{
	//////////////////1.快速排序////////////////////////
	//<1>源码  <2>伪代码  <3>时间复杂度分析
	//--------<1>源码---------
	//如果数组的元素不是基本数据类型,而是对象,那么对应的类需要重载
	//快速排序:从小到大 1->2
	template
	void quicksort12(T *A,int p,int r)
	{
		if(p < r)
		{
			int q = no_partition12(A,p,r);
			quicksort12(A,p,q-1);
			quicksort12(A,q+1,r);
		}
	}

	template
	int no_partition12(T *A,int p,int r)
	{
		T x = A[r];
		int i = p - 1;
		for(int j = p; j < r; j++)
		{
			//如果数组A的元素是类对象,
			//那么只有当该类重载了“<=”运算符后才能使用本模板
			//(也就是只有当该类重载了“<=”运算符后才能通过编译),下同
			if(A[j] <= x)
			{
				i = i + 1;
				exchange(A[i],A[j]);
			}
		}
		exchange(A[i+1],A[r]);


		return i+1;
	}
	//快速排序:从大到小 2->1
	template
	void quicksort21(T *A,int p,int r)
	{
		if(p < r)
		{
			int q = no_partition21(A,p,r);
			quicksort21(A,p,q-1);
			quicksort21(A,q+1,r);
		}
	}

	template
	int no_partition21(T *A,int p,int r)
	{
		T x = A[r];
		int i = p - 1;
		for(int j = p; j < r; j++)
		{
			if(A[j] >= x)
			{
				i = i + 1;
				exchange(A[i],A[j]);
			}
		}
		exchange(A[i+1],A[r]);
		return i+1;
	}

	//元素交换
	template
	void exchange(T &a,T &b)
	{
		//如果出现数组越界,是不能使用try-catch来捕捉的
		T m = a;
		a = b;
		b = m;
	}

/*

调用简例:

array[10];

htx::quicksort12(array,0,9);

*/

	/*--------<2>伪代码---------
	QUICKSORT(A,p,r)
	if p < r
	q = PARTITION(A,p,r)
	QUICKSORT(A,p,q-1)
	QUICKSORT(A,q+1,r)

	PARTITION(A,p,r)
		x = A [ r ]
		i = p - 1
		for j = p to r - 1
			if A[ j ] <= x
				i = i + 1
				exchange A [ i ] with A [ j ]
		exchange A [ i+1 ] with A [ r ]
		return i + 1
	*/

	/*--------<3>时间复杂度分析---------
	最好:O(n) = nlog(2)n
	平均:O(n) = nlog(2)n
	最坏:O(n) = n^2

	提示:可以按照描述自己画一下图
	1.根据上述伪代码可知,快速排序函数是分两路递归的函数
	2.那么将这个函数的递归路径画成二叉树的形式,设同一个函数体里面的两个子递归路径是同一层,即二叉树的两个子节点
	3.同一父节点下的两个子节点就是同一个函数体内的两个递归调用的“代价”(就是花多少时间)
	4.现在,假设“所有”父节点下的两个子节点的代价是成比例的,本例设为 1:9
	5.有了比例(1:9),我们就可以算出这个二叉树的高度了,假设为 h
	6.假设数组有n个元素,那么根节点的值就是n,即第一次循环的代价是c*n(c是常数,下同)
	7.而位于末端的所有子节点的代价“至少”为1(有可能是2),因为PARTITION的循环次数至少为1
	8.那么 n * (9/10)^h = 1  得到 h = log(10/9)n    (如 log(a)b : 以a为底b的对数)
	9.而二叉树每一层的代价和 <= c*n ,那么 总代价 = c*n*log(10/9)n
	10.那么再在最好的情况下的比例是1:1,此时的 总代价 = c * n * log(2/1)n = c*n*log(2)n = nlog(2)n
	11.所以最好的情况下是 O(n) = nlog(2)n;

	12.如果你给的待排序数组数据是随机的,那么一直发生1:9这样悬殊的比例的概率是很小的。
	13.也就是说比1:9的情况好,那么平均情况下就是接近 nlog(2)n 了。

	14.至于最坏的情况,这里给个例子: 2 3 4 5 6 1 ,按照代码执行,代价为 5 4 3 2 1
	15.写成公式: (1+(n-1)) * n / 2 = n^2/2  所以 最坏的情况下 O(n) = n^2
	*/

}

你可能感兴趣的:(编程通用)