c++实现快速排序
来源:互联网 发布:mac高光修容液 编辑:程序博客网 时间:2024/06/03 17:28
1、算法思想
快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序。它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod) ,分治法的基本思想是:将原问题分解为若干个规模更小但结构与原问题相似的子问题。递归地解这些子问题,然后将这些子问题的解组合为原问题的解。
2、快排步骤:
①分解:
在R[low..high]中任选一个记录作为基准(Pivot),以此基准将当前无序区划分为左、右两个较小的子区间R[low..pivotpos-1)和R[pivotpos+1..high],并使左边子区间中所有记录的关键字均小于等于基准记录(不妨记为pivot)的关键字pivot.key,右边的子区间中所有记录的关键字均大于等于pivot.key,而基准记录pivot则位于正确的位置(pivotpos)上,它无须参加后续的排序。
注意:划分的关键是要求出基准记录所在的位置pivotpos。划分的结果可以简单地表示为(注意pivot=R[pivotpos]): R[low..pivotpos-1].keys≤R[pivotpos].key≤R[pivotpos+1..high].keys 其中low≤pivotpos≤high。
②求解:
通过递归调用快速排序对左、右子区间R[low..pivotpos-1]和R[pivotpos+1..high]快速排序。
③组合:
因为当"求解"步骤中的两个递归调用结束时,其左、右两个子区间已有序。对快速排序而言,"组合"步骤无须做什么,可看作是空操作。
通俗理解核心步骤:
1.i =L; j = R; 将基准数备份形成第一个可以看成空值的a[i]。
2.j--由后向前找比它小的数,找到后把此数填前一个a[i]中。
3.i++由前向后找比它大的数,找到后也把此数填到前一个坑a[j]中。
4.再重复执行2,3二步,直到i==j,将基准数填入a[i]中
3、算法性能
时间复杂度:O(n*lgn)
最坏:O(n^2)
空间复杂度:O(n*lgn)
不稳定。
实现代码:
//先上递归版#include <stdio.h>#include <stdlib.h>#include <iostream>#include <time.h>#include <stack>
using namespace std;#define MAX 101int Partition(int num[], int low, int high){ //int pivotkey;这个枢轴的选取很关键,改进版的可以用三数取中,就九数取中等int pivotkey = num[low]; //在这里就取第一个元素num[0] = pivotkey; //备份到num【0】,while (low < high){while (low < high&&num[high] >= pivotkey)high--;num[low] = num[high]; //不满足循环条件就执行这个语句,因为备份出【low】,所以可以覆盖他,这也是这个while在 //前面的原因。否则【high】会丢失的。while (low < high&&num[low] <= pivotkey)low++;num[high] = num[low]; //交换low,是因为low=pivotkey,比较了。}num[low] = num[0];return low; //最后high和low在某一个位置相遇,就是切分部的值。}void Qsort1(int num[], int low, int high) //对随机产生的无序数组进行快速排序,这也是二分法的缺陷之一。{ //快排对很多数据更有优势,可以设置一个数据个数的阈值,才进行快排,这里也是一个优化的地方int pivot;//if (low < high){pivot = Partition(num, low, high); //轴值所在的位置Qsort1(num, low, pivot - 1); //递归的深度决定了时间的复杂度。Qsort1(num, pivot + 1, high);}}//非递归版,模拟栈的inline void push2(stack<int> &s, int l, int r){s.push(r);s.push(l);}void Qsort(int num[], int l, int r){stack<int> s;push2(s, l, r);int lwalker, rwalker, mid;while (!s.empty()){int left = s.top(); s.pop();int right = s.top(); s.pop();lwalker = left;rwalker = right;mid = num[(lwalker + rwalker) / 2];while (lwalker < rwalker){while (num[lwalker] < mid) lwalker++;while (num[rwalker]>mid) rwalker--;if (lwalker <= rwalker){int tmp = num[lwalker];num[lwalker] = num[rwalker]; num[rwalker] = tmp;lwalker++;rwalker++;}}if (lwalker < right) push2(s, lwalker,right);if (rwalker>left) push2(s, left, rwalker);}}void input(int num[])//实参传入的数组的首地址,而不是整个数组{int i;srand((unsigned)time(NULL));//产生随机函数的随机数种子for (i = 1; i < MAX; i++){num[i] = rand() % 100;}}void output(int num[]){int i;for (i = 1; i <= MAX; i++){printf("%5d", num[i]);if (i % 100 == 0)printf("\n");}}void main(){ int num[MAX],num2[MAX];time_t start, end;time(&start);input(num);cout << "递归排序前:" << endl;output(num);Qsort1(num, 0,MAX - 1);cout << "递归排序后:" << endl;output(num);input(num2);cout << "开始非递归排序,排序前:"<<endl; output(num2);cout << "非递归排序后:" << endl;Qsort(num2, 0, MAX - 1);output(num2);time(&end);cout << "用时为" << end-start << endl;system("pause");}
- 快速排序c实现
- 快速排序C实现
- 快速排序C实现
- 快速排序C实现
- 快速排序(C实现
- 快速排序 C语言实现
- 快速排序C语言实现
- 快速排序算法(c#)实现
- c语言实现快速排序
- C/C++实现快速排序
- C语言实现快速排序
- 快速排序实现(C语言)
- 快速排序C语言实现
- Xcode(C++) 快速排序实现
- C语言实现快速排序
- 快速排序C语言实现
- 快速排序C语言实现
- C语言实现快速排序
- Codeforces Round #352 (Div. 2)(B)思维
- android定时器
- 手动显示光标及软键盘
- 已知每个部门有一个经理,统计输出部门名称、部门总人数、 总工资和部门经理。
- 字符串算法之字典树
- c++实现快速排序
- 第14周阅读程序1(2)
- linux下redis 安装及遇到的问题解决
- 反转整数
- 泛型编程简化findViewById
- java.util.List的remove()方法使用技巧
- Swift-guard & defer
- A+B Problem (64bit Integer + EOF)
- FutureTask 源码解析