C++之快速排序

快速排序顾名思义是目前实践中最快的排序算法。如归并排序算法一样,快速排序算法也使用了分治的递归思想。快速排序的思想:选取枢纽元,同过枢纽元对数据进行分割,左边的数据小于枢纽元,右边的数据大于枢纽元。然后利用分治递归的思想,对左右数据进行分割,最后进行合并。枢纽元的选取对快速排序非常重要!!

怎么选取枢纽元呢?有的人会说选第一个或者最后一个数据。可以这样选择。但是如果出现第一个数据或者最后一个数据是最小的数据,那么其快速排序的效率将到达最低O(log N^2)。那么就随机选择枢纽元吧!当然可以啊,但是随机数的生成需要借助随机数发生器和引擎,其代价相当高,最终也会导致快速排序的效率降低。综上所述,我们使用三数中值法来选取枢纽元。三数中值分割法的思想:选择左端(Left),右端(Right),中间值(Center)的中值为枢纽元。

HubElem Median(int arrays[], int left, int right) {
	auto center = (left + right) / 2;
	if (arrays[left] > arrays[center])
		std::swap(arrays[left], arrays[center]);
	if (arrays[left] > arrays[right])
		std::swap(arrays[left], arrays[right]);
	if (arrays[center] > arrays[right])
		std::swap(arrays[center], arrays[right]);

	std::swap(arrays[center], arrays[right - 1]);
	return arrays[right - 1];
}
#include<iostream>
const int Cutoff = 3;
typedef int HubElem;
HubElem Median(int* arrays, int left, int right) {
	auto center = (left + right) / 2;
	if (arrays[left] > arrays[center])
		std::swap(arrays[left], arrays[center]);
	if (arrays[left] > arrays[right])
		std::swap(arrays[left], arrays[right]);
	if (arrays[center] > arrays[right])
		std::swap(arrays[center], arrays[right]);

	std::swap(arrays[center], arrays[right - 1]);
	return arrays[right - 1];
}

void InsertionSort(int* arrays, int N) {
	for (int i = 1; i < N; ++i) {
		int j = 0;
		auto temp = arrays[i];
		for (j = i; j > 0 && arrays[j - 1] > temp; --j)
			arrays[j] = arrays[j - 1];

		arrays[j] = temp;
	}
}

void QuickSort(int* arrays, int left, int right) {
	if (left + Cutoff <= right) {
		auto pivot = Median(arrays, left, right);
		auto i = left;
		auto j = right - 1;
		while (true) {
			while (arrays[++i] < pivot);
			while (arrays[--j] > pivot);
			if (i < j)
				std::swap(arrays[i], arrays[j]);
			else
				break;
		}
		std::swap(arrays[i], arrays[right - 1]);
		QuickSort(arrays, left, i - 1);
		QuickSort(arrays, i + 1, right);
	}
	else
		InsertionSort(arrays + left, right - left + 1);
}

int main(void)
{
	int arrays[] = { 1,4,7,2,5,8,3,6,9,10,12,45,78,13,16,52,26 };
	QuickSort(arrays, 0, sizeof(arrays) / sizeof(arrays[0]) - 1);
	for (const auto& x : arrays) {
		std::cout << x << std::endl;
	}
}

 

总结:1.本来想用vector代替数组的,结果会发生越界。vector是自动伸缩的数组,会导致其size无限大。求大佬帮我解决这个问题。

            2.当数据的大小小于10时,插入排序或者希尔排序要比快速排序效率高。

发布了50 篇原创文章 · 获赞 11 · 访问量 4088

猜你喜欢

转载自blog.csdn.net/qq_43145594/article/details/103000398