快速排序
快速排序,是一种分治算法。
分治算法解法步骤
分解:将要解决的问题分解为若干个规模较小、相互独立、与原问题形式相同的子问题
治理:求解各个子问题。由于各个子问题与原问题形式相同,只是规模较小而已,而当子问题划分得足够小时,就可以用简单的方法解决。
合并:按原问题的要求,将子问题的解逐层合并构成原问题的解。
快速排序算法设计
快速排序是比较快的排序方法。它的基本思想是通过一组排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据小,然后再按此方法对这两部分数据进行快速排序,整个排序过程可以递归进行,以此使所有数据变成有序序列。
分解:先从数列中取出一个元素作为基准元素。一基准元素为标准,将问题分解为两个子序列,使小于或者等于基准元素的子序列在左侧,使大于基准元素的子序列在右侧。
治理: 对两个子序列进行快速排序(递归快速排序)。
合并:将排好的两个子序列合并在一起,得到原问题的解。
算法分析
假设当前的待排序的序列为 R[low,hight] , 其中 low<=hight。同时选取首元素为基准元素。
步骤一:选取首元素的第一个元素作为基准元素 pivot=R[low] ,i=low ,j=hight。
步骤二:从右向左扫描,找到小于等于 pivot 的数,如果找到,R[i] 和 R[j] 交换 ,i++。
步骤三:从左向右扫描,找到大于 pivot 的数,如果找到,R[i] 和 R[j] 交换,j–。
步骤四:重复 步骤二和步骤三,直到 j 与 i 的指针重合 返回位置 mid=i ,该位置的数正好是 pivot 元素。
int partition(vector<int>& nums, int low, int high) {
int i = low, j = high;
int pivot = nums[low];//基准元素
while (i < j) {
//从右边开始寻找比pivot小的数
while (i < j && nums[j] > pivot)
--j;
if (i < j)
swap(nums[i++], nums[j]); //nums[i],nums[j]交换后,i向右移动一位
//从左边开始寻找比pivot大的数
while (i < j && nums[i] < pivot) ++i;
if (i < j)
swap(nums[i], nums[j--]); //nums[i],nums[j]交换后,j向左移动一位
}
return i; //最后i == j,返回最终划分完成后基准元素所在的位置
}
void quickSort(vector<int>& nums, int low, int high) {
if (low < high) {
int mid = partition(nums, low, high);
quickSort(nums, low, mid - 1);
quickSort(nums, mid + 1, high);
}
}
int main() {
vector<int> nums{ 30, 24, 5, 58, 18, 36, 12, 42, 39 };
cout << "排序前:";
for (int num : nums)
cout << num << " ";
cout << endl;
quickSort(nums, 0, nums.size() - 1);
cout << "排序后:";
for (int num : nums)
cout << num << " ";
cout << endl;
}
结果:
排序前:30 24 5 58 18 36 12 42 39
排序后:5 12 18 24 30 36 39 42 58
参考:sunny-ll