排序算法:快速排序
引言
在今天的文章中,我们将探讨一个经典的算法问题——“快速排序”(Quick Sort),快速排序以其高效的平均时间复杂度而闻名。
快速排序是一种高效的排序算法,它采用分治法的思想,将大问题分解为小问题来解决,从而提高了排序的效率。在实际场景中,快速排序有着广泛的应用,以下是两个具体的例子:
1. 数据库索引构建
在数据库中,快速排序常用于构建索引。数据库索引是帮助数据库管理系统高效获取数据的数据结构,它可以极大地提高数据检索的速度。当需要对数据库表中的数据进行排序以构建索引时,快速排序算法由于其平均时间复杂度为O(n log n),能够高效地完成排序任务。通过对数据库表中的数据进行排序,可以加速对数据的检索操作,提高数据库查询性能。例如,在电商网站的商品数据库中,使用快速排序对商品信息(如价格、上架时间等)进行排序,可以加快用户搜索和筛选商品的速度。
2. 搜索引擎中的排名
搜索引擎需要对海量的网页、文档等进行排序,以提供与用户查询最相关的搜索结果。在这个过程中,快速排序算法发挥着重要作用。搜索引擎会根据一定的算法(如PageRank等)对网页进行评分,并使用快速排序等排序算法对评分结果进行排序,以确保用户能够看到最相关的搜索结果。由于搜索引擎需要处理的数据量非常大,因此快速排序的高效性显得尤为重要。通过快速排序算法,搜索引擎能够在短时间内完成大量数据的排序任务,为用户提供快速、准确的搜索结果。
除了上述两个例子外,快速排序还在许多其他实际场景中得到应用。例如,在文件系统中对文件或目录进行排序、在编译器优化过程中对符号表进行排序、在财务系统中对交易记录进行排序等。这些应用场景都充分展示了快速排序算法在实际问题解决中的广泛性和重要性。
问题描述
对[49,38,65,97,76,13,27,49]这个数组进行快速排序
解题思路
快速排序是通过一趟排序,选取一个基准值,将将要排序的数组分割成独立的两部分,一部分的所有数据都小于基准值,另一部分的所有数据都大于基准值,然后递归地对这两部分进行同样地操作,从而达到整个数组变成有序序列。
代码实现
class Solution {
public:
vector<int> sortArray(vector<int>& nums) {
QuickSort(nums,0,nums.size()-1);
return nums;
}
void QuickSort(vector<int>& nums,int low, int high) {
if(low<high){
int pivotpos = Partition(nums,low,high);
QuickSort(nums,low,pivotpos-1);
QuickSort(nums,pivotpos+1,high);
}
}
int Partition(vector<int>& nums,int low ,int high)
{
int pivot = nums[low];
while(low < high){
while(low < high && nums[high] >= pivot)
--high;
nums[low] = nums[high];
while(low < high && nums[low] <= pivot)
++low;
nums[high] = nums[low];
}
nums[low] = pivot;
return low;
}
};
优化思路:三数取中法
为了解决在上述代码中,最差情况(有序序列)的时间复杂度为O(n²)的情况
class Solution {
public:
vector<int> sortArray(vector<int>& nums) {
QuickSort(nums,0,nums.size()-1);
return nums;
}
void QuickSort(vector<int>& nums,int low, int high) {
if(low<high){
int pivotpos = Partition(nums,low,high);
QuickSort(nums,low,pivotpos-1);
QuickSort(nums,pivotpos+1,high);
}
}
int Partition(vector<int>& nums,int low ,int high)
{
//确定基准元素(三数取中法)
int mid = low+(high-low)/2;
//以下三行为三数排序的方法
if (nums[low] > nums[mid]) std::swap(nums[mid], nums[low]);
if (nums[low] > nums[high]) std::swap(nums[low], nums[high]);
if (nums[mid] > nums[high]) std::swap(nums[mid], nums[high]);
//对low和mid做交换,使中间值位于最左边
std::swap(nums[mid], nums[low]);
int pivot = nums[low];
while(low < high){
while(low < high && nums[high] >= pivot)
--high;
nums[low] = nums[high];
while(low < high && nums[low] <= pivot)
++low;
nums[high] = nums[low];
}
nums[low] = pivot;
return low;
}
};
优化思路:随机选择法
class Solution {
public:
vector<int> sortArray(vector<int>& nums) {
QuickSort(nums,0,nums.size()-1);
return nums;
}
void QuickSort(vector<int>& nums,int low, int high) {
if(low<high){
int pivotpos = Partition(nums,low,high);
QuickSort(nums,low,pivotpos-1);
QuickSort(nums,pivotpos+1,high);
}
}
int Partition(vector<int>& nums,int low ,int high)
{
//随机选择法
srand(time(NULL));
int range = high - low + 1;
int randomIndex = low + rand() % range;
// 将随机选择的元素与第一个元素交换
std::swap(nums[low], nums[randomIndex]);
int pivot = nums[low];
while(low < high){
while(low < high && nums[high] >= pivot)
--high;
nums[low] = nums[high];
while(low < high && nums[low] <= pivot)
++low;
nums[high] = nums[low];
}
nums[low] = pivot;
return low;
}
};