使用C++实现快速排序QuickSort

参考了weiss的《数据结构与算法分析》的C++描述第三版。

快速排序原理其实很简单,是一个递归的过程。首先确定一个枢纽元,然后把大于枢纽元的元素放在左边,把小于枢纽元的元素放在右边。然后再对左右两边的子序列不断的重复这个操作(确定枢纽元,然后把大小元素归类),直到子序列中的元素为0个或1个的时候结束。

需要注意的两个地方:第一个是枢纽元的选取。最好不要直接选择序列的第一个元素作为枢纽元,因为在待排序列较为有序的时候,可能会一直处于最坏的情形。常见的选取方法是三数取中(详细的可见下面的程序)。

第二个需要注意的地方是如何处理等于枢纽元的元素。对于从两边往中间走的游标i和j来说,如果遇到等于枢纽元的元素,就应该让i和j停止。

程序如下:

#include
#include
#include
#include
#include
#include
using namespace std;

/*
* 快速排序通过递归实现,因此该函数为驱动函数
*/
template
void quickSort(vector & a)
{
	quickSort(a, 0, a.size() - 1);
}

/*
* 通过“三数选中”的方法选择枢纽元
* 找到枢纽元后,放在right-1的位置上
*/
template
const Comparable & median3(vector &a, int left, int right)
{
	//从对left,center,right位置上的三个数进行排序
	int center = (left + right) / 2;
	if (a[center] < a[left])
		swap(a[left], a[center]);
	if (a[right] < a[left])
		swap(a[right], a[left]);
	if (a[right] < a[center])
		swap(a[right], a[center]);

	//此时left、center、right位置上的数从小到大排序,且center位置上的元素为枢纽元
	//现在把center上的枢纽元放在right-1 的位置上
	swap(a[center], a[right - 1]);
	
	return a[right - 1];

}
/*
 快速排序主要的函数
 a表示待排的向量
 left表示子序列的最左边元素下标
 right表示子序列的最右边元素的下标
*/
template
void quickSort(vector & a, int left, int right)
{
	if (left + 10 < right)
	{
		Comparable pivot = median3(a, left, right);
		int i = left;
		int j = right - 1;
		while (1)
		{
			while (a[++i] < pivot);
			while (a[--j] > pivot);
			//因为如果i和j遇到等于枢纽元的元素,就让i和j都停止
			if (i < j)
				swap(a[i], a[j]);
			else
				break;
		}
		swap(a[i], a[right - 1]);//把枢纽元放回在相应的位置
		quickSort(a, left, i - 1);//把小于枢纽元的集合排序
		quickSort(a, i + 1, right);//把大于枢纽元的集合排序
	}
	else
	{
		insertionSort(a, left, right);
	}
	
}


/*
 在快速排序递归的时候,如果向量长度小于10就用插入排序
*/
template
void insertionSort(vector & a, int left, int right)
{
	for (int p = left + 1; p <= right; ++p) // 从第二个数开始  
	{
		Comparable tmp = a[p];
		int j = p;
		for (; j > left && a[j - 1] > tmp; --j)
			a[j] = a[j - 1];
		a[j] = tmp;
	}
}

/*输出向量*/
template
void printVector(vector & v)
{
	copy(v.cbegin(), v.cend(), ostream_iterator(cout, " "));
	cout << endl;
}

int main()
{
	vector source;
	uniform_int_distribution u(0, 10);
	default_random_engine e(static_cast(time(0)));
	for (int i = 0; i < 31; i++)
	{
		source.push_back(u(e));
	}

	cout << "排序前:" << endl;
	printVector(source);

	quickSort(source);

	cout << "排序后:" << endl;
	printVector(source);

	return 0;
}

结果如图(以含有多个相同元素的序列为例)

使用C++实现快速排序QuickSort_第1张图片

你可能感兴趣的:(算法)