基础算法(2):快速排序(随机划分+三数取中划分+ 随机三数取中划分+尾递归)

快速排序:

简介:快速排序是一种排序算法,包含n个数的输入数组,最坏情况为O(n^2),但是平均性能非常好: 期望运行时间为O(n*lg(n))。

基本思想:通过 一次划分得到一个主元在集合中的位置。

影响因素:划分算法决定着一个快速排序的效率。

                  

划分算法分类

1.以集合尾元素(或首元素)为主元,以下代码以尾元素为主元。                         

int partion(vector<int> &num, int beg, int end)
{
	/*把最后集合最后一个元素作为主元*/
	int x = num[end];
	int i = beg - 1;
	for (int j = beg; j != end; ++j)
	{
		if (num[j] <= x)
		{
			++i;
			swap(num[i], num[j]);
		}
	}
	swap(num[i + 1], num[end]);
	return i + 1;
}

void quickSort(vector<int> &num, int beg, int end)
{
	if (beg < end)
	{
		int q = partion(num, beg, end);
		quickSort(num, beg, q - 1);
		quickSort(num, q + 1, end);
	}
}

2. 随机数划分:随机选取数组中的一个元素为主元。随机数划分需要获得随机数,代码如下:

          1)   头文件

#include <ctime>
#include <cstdlib>

           2)在main() 函数调用random()前设置随机种子:

srand(unsigned(time(0)));// srand函数要在main函数开始的时候设置

           3)  写随机函数

int random(int start, int end)// 返回[start, end]之间的随机数
{
	return start + (end - start + 1)*rand() / (RAND_MAX + 1);//[start, end]
	//return start + (end - start)*rand() / (RAND_MAX + 1);//[start, end)
	//return start + 1 + (end - start)*rand() / (RAND_MAX + 1);//(start, end]
}

3.三数取中划分:取集合中的首元素,中元素,尾元素,以其中位数为主元。

int findMedian(const int &a, const int &b, const int &c)//取三个数的中位数
{
	if (a <= b && a <= c)
	{
		if (b <= c)
			return b;
		else
			return c;
	}
	else if (b < a && b <= c)
	{
		if (a <= c)
			return a;
		else
			return c;
	}
	else
	{
		if (a <= b)
			return a;
		else
			return b;
	}
}

 4.随机三个数取中位数。

/*3种划分算法*/
int rand_Partion(vector<int> &num, int beg, int end)
{
	//int temp = random(beg, end);
	//swap(num[temp], num[end]);
	/*以上随机返回[beg, end]数组中的一个数作为主元(pivot element);
	 *并把数组尾元素与这个随机数交换,因为partion()以最后一个数做主元
	 */

	//int a = random(beg, end);
	//int b = random(beg, end);
	//int c = random(beg, end);
	//int temp = findMedian(a, b, c);
	//swap(num[temp], num[end]);
	/*以上随机返回[beg, end]数组中的三个数,取三个数的中位数作为
	 *主元(pivot element);并把数组尾元素与这个中位数交换
	 */
	int a = num[beg];
	int b = num[beg + (end - beg) / 2];
	int c = num[end];
	int temp = findMedian(a, b, c);
	/*以上取[beg, end]的首、尾、中间三个数,把三个数的中位数作为
	 *主元(pivot element);并把数组尾元素与这个中位数交换
	 */
	return partion(num, beg, end);//调用分割函数
}
void rand_quickSort(vector<int> &num, int beg, int end)
{
	if (beg < end)
	{
		int q = rand_Partion(num, beg, end);
		rand_quickSort(num, beg, q - 1);
		rand_quickSort(num, q + 1, end);
	}
}

快速排序的尾递归: 

quickSort()中的第二次递归调用并不是必须的,可以用迭代控制结构替代它。

void quickSort_2(vector<int> &num, int beg, int end)//尾递归形式
{
	while (beg < end)
	{
		int q = partion(num, beg, end);
		quickSort_2(num, beg, q - 1);//一次循环把主元左边的排序好
		beg = q + 1;
	}
}

                  

    原文作者:排序算法
    原文地址: https://blog.csdn.net/l_200691/article/details/17239495
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞