注意一个C++的坑
sizeof()
这个函数静态数组可以求长度,动态new出来的数组不行,因为针对的是指针……,不过既然的动态数组了,其长度本身必然是一个变量了,你没有必要这么求长度。
下面看快速排序的代码。
#include <iostream>
#include <algorithm>
using namespace std;// divide 比基准点小的放左边,大的放右边,返回基准点Index
// 对于快速排序,重点是【划分策略】
// “=”的有无,取决于极端情况,可以使用极端序列快速判定
// 例如 5 4 3 2 1
// 需要关注几个状态的特征即可:初态,动态过程中的临界,终态
int partition_array(int data[], int min,int max) {int left_pointer = min + 1; // 以data[min]为基准值int right_pointer = max;int standard_value = data[min];while (left_pointer <= right_pointer){while (data[left_pointer] <= standard_value && left_pointer <= max) // 后面的必须是 <=,不能是 < left_pointer++; // left = max 极端临界状态while (data[right_pointer] > standard_value) // 不可能小于最小边界,因为[min]是标准值的位置right_pointer--;if (left_pointer < right_pointer) {swap(data[left_pointer], data[right_pointer]);left_pointer++;right_pointer--;}}// 【结束状态】// 置换结束之后,right指向的是比基准值小的,left指向的是比基准值大的,所以换rightswap(data[right_pointer], data[min]); return right_pointer;
}void quick_sort(int data[], int min, int max) {// conquerif (min >= max)return;else{// divide [ small | standard | large ]int standard_value_index = partition_array(data, min, max);quick_sort(data, min, standard_value_index - 1);quick_sort(data, standard_value_index + 1, max);}// don't need merge
}int main() {cout << "start" << endl;int a[] = { 5,4,3,2,1 };int length = sizeof(a) / sizeof(a[0]);quick_sort(a, 0, length - 1);for (int i = 0; i < length; i++) {cout << a[i] << " ";}return 0;
}
把握排序算法
- 分:重点,做出简单的排序,将基准线放中间,左边都小,右边都大
- 治:一个元素或者无元素,一定有序
- 合:不需要合,自然有序
对于分的策略,注意几个问题
- 几个状态
- 初态
- 动态
- 终态
在初态,选择一个基准点,然后依次比较后面的元素。
动态过程中,注意等号问题,选取极端情况(比如完全倒序),快速判定有无等号。
终态:左指针指向大的,右指针指向小的,左指针在右指针的右边
对于终态之后,我们将右指针的元素与基准元素换位,就可以获取我们最初的划分目标,之后再进行递归和治理。
对于之前的归并排序,重点是合的策略,而快速排序重点则是分的策略。
但是它们都是分、治、合的分治策略,只不过侧重点不同。