设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用数组的第一个数)作为主元,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。值得注意的是,快速排序不是一种稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动。
1)设置两个变量i、j,排序开始的时候:i=0,j=N-1;
2)以第一个数组元素作为关键数据,赋值给key,即key=A[0];
3)从j开始向前搜索,即由后开始向前搜索(j--),找到第一个小于key的值A[j],将A[j]和A[i]互换;
4)从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于key的A[i],将A[i]和A[j]互换;
5)重复第3、4步,直到i=j;
快排的时间复杂度O(nlogn)
 
快排的非递归实现,主元并没有随机选取。
#include <stdlib.h>
#include <stdio.h>
#include <vector>
#include <stack>
int partition(int a[], int left, int right) //partition函数以第一个元素作为pivot
{
if(a == NULL) //做异常处理
return -1;
if(left >= right)
return -1; int X = a[left];
int i = left;
int j = right; while(i < j)
{
while(i < j && a[j] > X) //从最右边找到第一个小于pivot的元素
j--;
if(i < j) //因为上面的循环出来可能i == j,所以如果i < j再令a[i] = a[j] 且 i = i + 1;
a[i++] = a[j]; //因为第一个元素是pivot已经被记录为X了,所以数组可以看做有一个空位在a[first](a[i])
while(i < j && a[i] <= X)
i++;
if(i < j)
a[j--] = a[i]; //因为a[j]已经在上面移到了a[first],所以a[j]是一个空位,可以用a[i]赋值
}
a[i] = X;
return i;
} void stack_implement_quickSort(int a[], int left, int right)
//如果之前看懂了如何非递归先序遍历二叉树,这个程序应该很好理解
{
std::stack<std::pair<int, int> > s;
int mid = partition(a, left, right); if(mid == -1)
return;
if(left < mid-1)
{
s.push(std::make_pair(left, mid-1));
}
if(mid+1 < right)
{
s.push(std::make_pair(mid+1, right));
} while(!s.empty())
{
std::pair<int,int> topPair = s.top();
s.pop(); mid = partition(a, topPair.first, topPair.second); if(mid == -1)
return;
if(topPair.first < mid-1)
{
s.push(std::make_pair(topPair.first, mid-1));
}
if(mid+1 < topPair.second)
{
s.push(std::make_pair(mid+1, topPair.second));
}
}
} int main(){
int a[] = {1,2,9,2,2,2,2,3,10,4,5,7,4};
stack_implement_quickSort(a, 0, 12);
return 0;
} /*采用递归的方法
void quickSort(int a[], int p, int q){
if (p <= q){
int r = partition(a, p, q);
if(r == -1)
return;
quickSort(a, p, r-1);
quickSort(a, r+1,q);
}
} int main(){
int a[] = {1,2,9,2,2,2,2,3,10,4,5,7,4};
quickSort(a, 0, 12);
int i = 0;
}
*/

随机选取主元:

#include <stdlib.h>
#include <stdio.h> int partition(int a[], int p, int q){
int pivot = rand() % (q-p+1) + p;
int i = p;
int j = q;
int key = a[pivot]; while(i < j){ while(i < j && a[i] < key){
i++;
}
if(i < j){
a[pivot] = a[i];
a[i] = key;
pivot = i;
} while(i < j && a[j] >= key){
j--;
}
if(i < j){
a[pivot] = a[j];
a[j] = key;
pivot=j;
}
}
return pivot;
} void quickSort(int a[], int p, int q){
if (p <= q){
int r = partition(a, p, q);
quickSort(a, p, r-1);
quickSort(a, r+1,q);
}
} int main(){
int a[] = {1,2,9,2,2,2,2,3,10,4,5,7,4};
quickSort(a, 0, 12);
int i = 0;
}

 

先贴上代码:Random快排,快排的非递归实现的更多相关文章

  1. 超实用的Eclipse快捷键大全(解密为什么他们的代码写的又快又好~)

    1.Ctrl+s:快速保存代码 一定要记得随时随地用Ctrl+s来保存我们的代码哦!!!不然等到电脑关机或者是使用的Eclipse突然闪退就欲哭无泪了.此时脑海里就突然出现了哔哔哔的画面~ 2.Alt ...

  2. 90% 的 Java 程序员都说不上来的为何 Java 代码越执行越快(2)- TLAB预热

    经常听到 Java 性能不如 C/C++ 的言论,也经常听说 Java 程序需要预热,那么其中主要原因是啥呢? 面试的时候谈到 JVM,也有很多面试官喜欢问,为啥 Java 程序越执行越快呢? 一般人 ...

  3. C语言 | 栈的应用 | 非递归栈实现快排

    /* 非递归栈实现快排 */ #include <stdio.h> #include <math.h>> #include <malloc.h> #inclu ...

  4. 归并非递归、快排递归及非递归的C++实现及时间效率对比。。

    今天看剑指offer突然发现下学期都要去面试了,还没自己实现过快排非递归和归并非递归,这怎么能行呢,于是就写了一下. (虽然有点卡壳,又回去翻了下算导,还是顺利写出来了) 先放图: 一亿数据量: #p ...

  5. OpenGL快问快答

    OpenGL快问快答 本文内容主要来自对(http://www.opengl.org/wiki/FAQ)的翻译,随机加入了本人的观点.与原文相比,章节未必完整,含义未必雷同,顺序未必一致.仅供参考. ...

  6. html5 vedio 播放器,禁掉进度条快进快退事件

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. 快读&快写模板【附O2优化】

    快读&快写模板 快读快写,顾名思义,就是提升输入和输出的速度.在这里简单介绍一下几种输入输出的优劣. C++ cin/cout 输入输出:优点是读入的时候不用管数据类型,也就是说不用背scan ...

  8. P1908 逆序对——树状数组&离散化&快读快写の学习

    题目简述: 对于给定的一段正整数序列,逆序对就是序列中 a_i>a_jai​>aj​ 且 i<ji<j 的有序对. 输出序列中逆序对的数目. 知识补充: 树状数组: 这东西就是 ...

  9. fzu Problem 2198 快来快来数一数 (快速幂+优化)

    题目链接: Problem  2198  快来快来数一数 题目描述: 给出n个六边形排成一排,a[i]代表i个六边形能组成的生成树个数,设定s[i]等于a[1]+a[2]+a[3]+....+a[i- ...

随机推荐

  1. js滚动到底部事件

    window.innerHeight表示窗口高度 $(document).height()返回文档高度 $(document).scrollTop()返回滚动条与顶部的距离,在最上部时为0,在最下部时 ...

  2. tornado和django的结合使用 tornado Server for django WSGI APP

    #!/usr/bin/env python # Run this with # Serves by default at # http://localhost:8080/hello-tornado a ...

  3. Sharepoint 杂记

    在Sharepoint中复制Settle.html,粘贴后改名为km.html,修改km.html会自动更新km.master,修改好模板后需要在站点发布. 添加List添加WebPart,继承KmW ...

  4. 模拟发送http请求

    1.httpie 2.postman:Postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件. 3.fiddler

  5. Linux不重启的情况下添加硬盘

    众所周知,SATA和SCSI是支持热插拔的,但是新装了这类支持热插拔的驱动器,系统不会马上识别的,往往我们需要重启系统来识别,但是有另外一种方法可以很方面的让系统识别新的设备.作为系统管理员,需要了解 ...

  6. spoj705 后缀数组求不同子串的个数

    http://www.spoj.com/problems/SUBST1/en/  题目链接 SUBST1 - New Distinct Substrings no tags  Given a stri ...

  7. Spring mvc-异常javax.servlet.ServletException: Could not resolve view with name 'xxx' in servlet with name 'spring'

    最近使用spring mvc开发项目,遇到一个问题: javax.servlet.ServletException: Could not resolve view with name 'ok' in ...

  8. Android 自定义Activity基类与TitleBar

    我们在开发App的时候有时候碰到多个界面有一个共同点的时候,比如,都有相同的TitleBar,并且TitleBar可以设置显示的文字.TitleBar上的点击事件,如果给每一个Activity都写一遍 ...

  9. 【CodeForces 672B】Different is Good

    题 字符串所有子串要不同.求修改最少多少个字符. 因为只能是26个字母,显然大于26的不可能有答案,其它情况ans+=u[i]-1:u[i]是字母出现的次数. #include<cstdio&g ...

  10. webuploader跨域上传

    浏览器在跨域请求前会发个options请求来验证是否跨域,所以后端再处理这个options请求时,要告诉浏览器一些信息. 也就是个header信息 header("Access-Contro ...