快速排序的基本思想:分治法。
通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。
快速排序使用分治法来把一个串(list)分为两个子串(sub-lists)。具体算法描述如下:
时间复杂度: 最佳情况:T(n) = O(nlogn) 最差情况:T(n) = O(n2) 平均情况:T(n) = O(nlogn)
空间复杂度:O(logn)
稳定性: 不稳定
基于比较的排序
1. 先把作为key的抠出来单独放置,key值位置为坑。
2. 从数组尾部开始往前找,找第一个比key小的数字,放在坑里,新坑出现。
3. 从数组头部开始往后找,找第一个比key大的数字,放在坑里,更新坑。
4. 直到前后游标重叠。将key放进最后这个坑里。这就完成了第一趟快排。
5. 对子序列递归执行1~4. 完成了最终的排序。
针对取最后一个元素作为枢轴的情况:
1、定义变量fast指向序列的开头,定义变量slow的前一个位置。
2、当array[fast] < key时,fast和slow同时往后走,如果array[fast]>key,fast往后走,slow留在大于key的数值前一个位置。
3、当array[fast]再次 < key时,交换array[fast]和array[slow]。
说白了就是,在没找到大于key值前,slow永远紧跟fast,遇到大于枢轴的值,两者之间就会拉开差距,中间差的肯定是连续的大于key的值,当再次遇到小于key的值时,交换两个下标对应的值就好了。
#include
#include
using namespace std;
int quick_sort2(vector& nums, int begin, int end) {
if (begin >= end) {
return 0;
}
int key = nums[begin];
int tmp, left = begin, right = begin + 1;
while (right != end) {
if(nums[right] < key) {
left++;
cout<<"while: left: " << left << " nums[left]:" << nums[left] << " right: " << right << " nums[right]:" << nums[right] << endl;
tmp = nums[right];
nums[right] = nums[left];
nums[left] = tmp;
}
right++;
}
cout<<"left: " << left << " nums[left]:" << nums[left] << " right: " << right << " nums[right]:" << nums[right] << endl;
tmp = nums[begin];
nums[begin] = nums[left];
nums[left] = tmp;
quick_sort2(nums, begin, left);
quick_sort2(nums, left + 1, end);
return 0;
}
int main(int argc, char* argv[]){
cout << "hello world\n";
// vector nums{10, 5, 4, -10, 2, 0};
int a[6] = {10, 5, 4, -10, 2, 0};
vector nums(a, a+6);
int i, length = (int)nums.size();
for(i =0 ; i < length; i++){
cout << nums[i] << ' ';
}
cout << endl;
// quick_sort(nums, 0, length - 1);
quick_sort2(nums, 0, length);
for(i =0 ; i < length; i++){
cout << nums[i] << ' ';
}
cout << endl;
/* for (auto i:nums){
cout << i << ' ';
}
*/
return 0;
}
基本思路:
1、选取一个关键字(key)作为枢轴,一般取整组记录的第一个数/最后一个为枢轴。
2、设置两个变量left = 0;right = N - 1;
3、从left一直向后走,直到找到一个大于key的值,right从后至前,直至找到一个小于key的值,然后交换这两个数。
4、重复第三步,一直往后找,直到left和right相遇,这时将key放置left的位置即可。
#include
#include
using namespace std;
int quick_sort(vector& nums, int i_begin, int i_end) {
if(i_begin >= i_end) {
return 0;
}
int key = nums[i_begin];
int left = i_begin;
int right = i_end;
while(left < right) {
while(left < right && nums[right] >= key) {
right --;
}
if (left < right) {
cout << "nums[" << left <<"] is " << nums[left] << "; nums[" << right << "] is " << nums[right]< nums{10, 5, 4, -10, 2, 0};
int a[6] = {10, 5, 4, -10, 2, 0};
vector nums(a, a+6);
int i, length = (int)nums.size();
for(i =0 ; i < length; i++){
cout << nums[i] << ' ';
}
cout << endl;
quick_sort(nums, 0, length - 1);
for(i =0 ; i < length; i++){
cout << nums[i] << ' ';
}
cout << endl;
/* for (auto i:nums){
cout << i << ' ';
}
*/
return 0;
}
思想:随机选择序列中的一个数作为key值。