Randomized quicksort

本文介绍了一种快速排序算法的两种不同实现方式:简单快速排序和随机化快速排序,并提供了详细的C++代码示例。简单快速排序在平均情况下具有O(nlog(n))的时间复杂度,但在数组已排序的情况下会退化到O(n*n)。随机化快速排序通过随机选择轴心元素来避免最坏情况的发生。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <vector>
#include <iostream>
#include <algorithm>
#include <Windows.h>

using namespace std;
// QuickSort(List A)
// if A size <= 1
//		return
// pick A[i] from A as pivot
// (L, M, R) <- partition-3way(A, i)
// QuickSort(List L)
// QuickSort(List R)

int partitionAtLast(vector<int> &arry, int start, int end)
{
	// choose the last element as pivot
	int i = start;
	for (int j = start; j <= end - 2; ++j)
		if (arry[j] <= arry[end - 1])
			swap(arry[i++], arry[j]);
	swap(arry[i], arry[end - 1]);
	return i;
}

void SimpleHelper(vector<int> &arry, int start, int end)
{
	if (start < end)
	{
		int pivot = partitionAtLast(arry, start, end);
		SimpleHelper(arry, start, pivot);
		SimpleHelper(arry, pivot + 1, end);
	}
}

// average case: O(nlog(n))
// the simple quick sort will degrade to O(n*n) if the array is sorted already
void quickSort_Simple(vector<int> &arry)
{
	SimpleHelper(arry, 0, arry.size());
}


void RandomizedHelper(vector<int> &arry, int start, int end)
{
	int i = start;
	int j = end - 1;
	int sz = end - start;
	int pivot;
	if (sz > 1)
	{
		pivot = rand() % sz + start;
		while (true)
		{
			while (arry[j] > arry[pivot] && j >= pivot)
				--j;
			while (arry[i] < arry[pivot] && i <= pivot)
				++i;
			if (i >= j)
				break;
			swap(arry[i], arry[j]);
		}
	}
	else
		return;

	RandomizedHelper(arry, start, pivot);
	RandomizedHelper(arry, pivot + 1, end);
}

void quickSort_Randomized(vector<int> &arry)
{
	RandomizedHelper(arry, 0, arry.size());
}

void printArray(const vector<int> &arry)
{
	for (int i = 0; i < arry.size(); cout << arry[i++] << " ");
	cout << endl;
}

int main()
{
	vector<int> arry{ 1, 8, 3, 5, 11, 9, 39, 21 };
	printArray(arry);
	quickSort_Randomized(arry);
	printArray(arry);
	system("PAUSE");
	return 0;
}

Reference:

http://www.cs.cmu.edu/~avrim/451f11/lectures/lect0906.pdf

http://www.cs.princeton.edu/~wayne/kleinberg-tardos/pdf/05DivideAndConquerI.pdf

快速排序(Quicksort)是一种广泛使用的排序算法,其平均时间复杂度为 O(n log n),但在最坏情况下可能退化为 O(n²)。为了在 Python 中优化快速排序,可以采用多种技术来提高其性能并减少最坏情况的发生概率。 ### 三重切分快速排序(3-Way Partitioning) 在传统快速排序中,如果输入数据中存在大量重复元素,性能可能会下降。三重切分快速排序将数组划分为三部分:小于、等于和大于基准值的元素。这种方法可以显著减少递归深度,并提高包含重复元素的数据集的排序效率。 ```python def quick_sort_3way(arr): if len(arr) <= 1: return arr elif len(arr) == 2: return [min(arr), max(arr)] else: left, mid, right = [], [], [] pivot = arr[len(arr) // 3] # 选取中间位置的元素作为基准 for x in arr: if x < pivot: left.append(x) elif x == pivot: mid.append(x) else: right.append(x) return quick_sort_3way(left) + mid + quick_sort_3way(right) ``` ### 随机化基准选择(Randomized Pivot) 为了减少最坏情况的发生概率,可以在选取基准元素时使用随机化策略。这样可以避免针对特定输入(如已排序数组)导致的性能下降问题。 ```python import random def quick_sort_randomized(arr): if len(arr) <= 1: return arr else: pivot = random.choice(arr) # 随机选择基准元素 left = [x for x in arr if x < pivot] mid = [x for x in arr if x == pivot] right = [x for x in arr if x > pivot] return quick_sort_randomized(left) + mid + quick_sort_randomized(right) ``` ### 小数组切换为插入排序(Hybrid with Insertion Sort) 对于小规模数据集,插入排序通常比快速排序更快。因此,在递归过程中,当子数组的大小小于某个阈值(例如 10 个元素),可以切换为插入排序以减少递归开销。 ```python def insertion_sort(arr): for i in range(1, len(arr)): key = arr[i] j = i - 1 while j >= 0 and arr[j] > key: arr[j + 1] = arr[j] j -= 1 arr[j + 1] = key return arr def quick_sort_hybrid(arr, threshold=10): if len(arr) <= threshold: return insertion_sort(arr) else: pivot = arr[len(arr) // 2] left = [x for x in arr if x < pivot] mid = [x for x in arr if x == pivot] right = [x for x in arr if x > pivot] return quick_sort_hybrid(left, threshold) + mid + quick_sort_hybrid(right, threshold) ``` ### 尾递归优化(Tail Recursion Elimination) Python 对递归深度有限制,默认递归深度限制为 1000。为了避免栈溢出问题,可以对快速排序进行尾递归优化,将递归调用转换为迭代方式,从而减少栈帧数量。 ```python def quick_sort_tail_recursive(arr): stack = [arr] result = [] while stack: current = stack.pop() if len(current) <= 1: result.extend(current) continue pivot = current[len(current) // 2] left = [x for x in current if x < pivot] mid = [x for x in current if x == pivot] right = [x for x in current if x > pivot] stack.append(right) stack.append(mid) stack.append(left) return result ``` ### 利用 NumPy 进行向量化操作(Vectorization with NumPy) 如果排序的数据集非常大且需要高性能,可以利用 NumPy 的向量化操作来替代 Python 原生的列表操作。NumPy 内部实现为 C 语言级别的操作,因此执行速度更快。 ```python import numpy as np def numpy_quicksort(arr): return np.sort(arr, kind='quicksort') # 使用 NumPy 的快速排序实现 ``` ### 总结 通过三重切分、随机化基准、混合插入排序、尾递归优化以及使用 NumPy 等技术,可以在 Python 中显著提升快速排序的性能。这些优化策略不仅提高了算法的效率,还增强了对不同输入模式的适应能力。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值