为了offer系列——快速排序(C++),附测试用例
2017-06-23 10:25
190 查看
offer必备三大算法之一——快速排序
平均时间复杂度:O(nlogn),和归并排序一样。尽管最坏时间复杂度很差,但因为它的平均性能非常好,故常用于实际当中。
稳定性:是一个不稳定的排序算法,不稳定发生在主元pivot和a[j]交换的时刻。
基本步骤(算法导论分治思想的三步)如下:
1.分解:将数组A[p,..,r]以一个主元pivot(常取最后一个元素A[r])为界,划分为两个子数组(可能为空,如2,3,4),A[p,..,q-1]和A[q+1,..,r],是的前一个数组的每一个元素都小于或等于主元,后一个数组元素都大于主元。
2.解决:通过递归调用快速排序,对上述分割的两个子数组排序(递归的分解,直到都剩一个元素)。
3.合并:因为子数组都是原址排序(常用排序算法中,只有归并算法不是原址排序),数组都已经有序,故不需要合并操作。
r是主元的位置,i从p的前一个元素开始,j从p开始。若A[j]不大于主元,则把A[j]和A[++i]交换位置;反之,j++;直到遍历了所有元素,再将末尾的主元放在i++的位置。
程序如下:
平均时间复杂度:O(nlogn),和归并排序一样。尽管最坏时间复杂度很差,但因为它的平均性能非常好,故常用于实际当中。
稳定性:是一个不稳定的排序算法,不稳定发生在主元pivot和a[j]交换的时刻。
基本步骤(算法导论分治思想的三步)如下:
1.分解:将数组A[p,..,r]以一个主元pivot(常取最后一个元素A[r])为界,划分为两个子数组(可能为空,如2,3,4),A[p,..,q-1]和A[q+1,..,r],是的前一个数组的每一个元素都小于或等于主元,后一个数组元素都大于主元。
2.解决:通过递归调用快速排序,对上述分割的两个子数组排序(递归的分解,直到都剩一个元素)。
3.合并:因为子数组都是原址排序(常用排序算法中,只有归并算法不是原址排序),数组都已经有序,故不需要合并操作。
r是主元的位置,i从p的前一个元素开始,j从p开始。若A[j]不大于主元,则把A[j]和A[++i]交换位置;反之,j++;直到遍历了所有元素,再将末尾的主元放在i++的位置。
程序如下:
//把原矩阵以主元pivot为界分成两个数组 void quick_s(int* A, int p, int r) { if (p < r) // 只有一个元素的数组不能分界 { int q = partition(A, p, r); quick_s(A, p, q - 1); // 分别对两个数组再分解 quick_s(A, q+1, r); } } // int partition(int* A, int p, int r) { int pivot = A[r]; int i = p - 1; //i从p的前一个开始! for (int j = p; j <= r-1; j++) //j作为遍历数组的变量,j <= r-1 { if (A[j] <= pivot) // 若A[j]不大于主元,则把A[j]和A[++i]交换位置;反之,j++; { i = i + 1; //int temp; int temp = A[j]; A[j] = A[i]; A[i] = temp; //swap(A[i], A[j]); } } //循环一遍后,将末尾的主元放在i++的位置 int temp2 = A[r]; //注意不要写成temp2 = pivot,结果是不一样的,大家可以试试。 A[r] = A[i + 1]; A[i + 1] = temp2; //也可以调用模板函数交换位置swap(A[i+1], A[r]); return i + 1; //返回主元的位置 } int _tmain(int argc, _TCHAR* argv[]) { int a[] = { 2, 8, 7, 4, 6, 3 }; cout << "Before quicksort:\n"; for (auto x : a) cout << x << endl; quick_s(a, 0, 5); //swap(a[0], a[1]); cout << "After quicksort:\n"; for (auto x : a) cout << x << endl; return 0; }
相关文章推荐
- 为了offer系列——二分查找(C++),附测试用例
- 【转】玩转Google开源C++单元测试框架Google Test系列(gtest)之五 - 死亡测试
- (转)玩转Google开源C++单元测试框架Google Test系列(gtest)之五 - 死亡测试
- C++性能测试用例
- 玩转Google开源C++单元测试框架Google Test系列(gtest)之五 - 死亡测试
- Google C++测试框架系列入门篇:第三章 基本概念
- Google C++ Test Framework (二)为用例中的测试进行统一的配置
- ACM输入输出--多组测试用例--C、C++、Java
- 性能测试案例模板 性能测试用例模板 测试案例 性能用例 模板 容我想想之性能测试系列培训
- 反转指向字符串反转C++实现源码(带测试用例)
- C++的性能C#的产能?! - .Net Native 系列《三》:.NET Native部署测试方案及样例
- 玩转 Google开源C++单元测试框架Google Test系列(gtest)之五 - 死亡测试(转载)
- Google C++单元测试框架(Gtest)系列教程之三——测试固件(Test fixture)
- Google C++单元测试框架(Gtest)系列教程之二——断言、函数测试
- 玩转Google开源C++单元测试框架Google Test系列(gtest)之五 - 死亡测试
- 测试系列之 c++ server测试全攻略
- ISTQB AL-TA/TTA连载系列08:如何有效减少测试用例数目
- Google C++单元测试框架(Gtest)系列教程之三——测试固件(Test fixture)
- Google C++测试框架系列入门篇:第一章 介绍:为什么使用GTest?
- C++的性能C#的产能?! - .Net Native 系列四:性能测试方法(PerfView)