1.前言
对初学递归的人来说,递归无疑是很不好理解的,本系列旨在对常见算法中使用的递归做一定程度的解析,学习这些算法的同时,总结出其递归模型。以便于加深对递归的理解,同时,当我们掌握了多种递归模型。那无论何时需要使用递归解决问题,我们都能从已有的递归模型中得到一些启发。或者相似的场景使用的模型是一样时(类似于数学或物理中的建模,通过对具有某类特征的事物的分析,总结出其一般规律,以便应用到具有相同特征的情况中去),我们便能套用已有的模型使用,相信会很方便。
2.快速排序
1.排序流程
摘自百度百科:
(1)首先设定一个分界值,通过该分界值将数组分成左右两部分。
(2)将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。此时,左边部分中各元素都小于或等于分界值,而右边部分中各元素都大于或等于分界值。
(3)然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理。
(4)重复上述过程,可以看出,这是一个递归定义。通过递归将左侧部分排好序后,再递归排好右侧部分的顺序。当左、右两个部分各数据排序完成后,整个数组的排序也就完成了。
2.代码实现
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <iostream>
#include <Windows.h>
using namespace std;
int QuitSort(vector<int>& nums,int left,int right) {
int tmp = nums[left];
while (left < right) {
while (left<right && nums[right]>tmp) --right;
if (left < right) nums[left] = nums[right];
while (left < right && nums[left] <=tmp ) ++left;
if (left < right) nums[right] = nums[left];
}
nums[left] = tmp;
return left;
}
int RepeatSort(vector<int>& nums, int left, int right) {
if (left > right) return 0;
int tmp = QuitSort(nums, left, right);
RepeatSort(nums, tmp + 1, right);
RepeatSort(nums, left, tmp - 1);
return 1;
}
int main(void) {
vector<int> nums = { 1,1,2,9,1,7,10,99,-20,0,2,7,10,99,150,555 };
for (auto& tmp : nums) cout << tmp << endl;
cout << endl;
RepeatSort(nums, 0, nums.size() - 1);
for (auto& tmp : nums) cout << tmp << endl;
system("pause");
return 0;
}
3.递归模型总结
int tmp = QuikSort(nums, left, right);
RepeatSort(nums, tmp + 1, right);
RepeatSort(nums, left, tmp - 1);
快速排序的递归模型其实和归并排序的很像,都是分治法的一种应用,通过把原问题一分为二,直至其被分为不可再分或者好解决的子问题(这个具体取决于设置的递归结束条件)唯一不同的是快速排序在进入下一层递归之前会先对原问题进行一定的处理,具体体现在QuikSort()函数上,该函数的功能是取一个基准数,然后把数据分为大于该基准数与小于该基准数的两部分,小于该基准数的放在数据的前半部分,大于的放在后半部分。注意此时数据并未有序,因为该函数仅仅只是把小于基准数的数全放到了基准数前面,把大于基准数的数放到了基准数的后面。但这前后两部分的数据并未有序。所以要继续递归下去。即RepeatSort(nums, tmp + 1, right); 与 RepeatSort(nums, left, tmp - 1); 两个函数,其实抽象或者宏观的来看,RepeatSort()函数就是实现把nums数组从tmp+1到right的数据排好序的功能。
RepeatSort()函数会逐层递归并选取基准数把数据分成两部分,直至left==right递归开始回升。
至此我们又知道了一种分治法应用的递归模型,即快速排序的先对数据进行处理,再两路递归下去的模型。
如果有兴趣的可以看看我写的归并排序的递归模型