排序算法总结(6)--快速排序

原创 2017年05月22日 21:15:22

一、简介

快速排序是冒泡排序的改进。可以看成是一个分治的过程。首先将数组A[p,…r]分成三部分:A[p,…,q-1],A[q],A[q+1,…,r],A[p,…,q-1]中的每一个元素都比A[q]小,而A[q+1,…,r]的每一个元素都比A[q]大。然后分别对A[p,…,q-1]和A[q+1,…,r]递归调用快速排序。当左右两部分排序好之后,即完成了整个数组的排序。
那么如何计算下标q是整个快速排序的关键。首先选择一个元素作为主元,围绕它来划分A[p,…r],这个主元也是最后的A[q]。划分过程中需要两个指针,一个j用来遍历数组,另一个i指向被交换的索引。从数组的左端开始遍历,如果A[j]小于主元,i++,并且A[i]和A[j]交换,如果大于等于主元,则不交换,当数组遍历完毕之后,将主元和A[i+1]交换。
快速排序是冒泡排序的改进。在冒泡排序中,每次循环改变一个元素的位置,并确定这个元素的位置,即将这个元素“浮”到最前面的位置。在快速排序中,每次改变多个元素的位置,并确定一个元素的位置,将这个元素“浮”到合适的位置。快速排序在每次循环中,交换的次数明显减少。

二、伪代码

2.1 递归

quickSort(A,p,r)
    if p<r
        q=partition(A,p,r)
        quickSort(A,p,q-1)
        quickSort(A,p+1,r)


partition(A,p,r)
    x=A[r]
    i=p-1
    for j=p tp r-1
        if A[j]<x
            i++
            swap(A[i],A[j])
    swap(A[i+1],A[r])
    return i+1

2.2 非递归

使用一个栈辅助,存储p,q,r

loopQuickSort(A)
    S=null  //创建一个栈
    start=0;
    end=A.length-1
    S.push(start)
    S.push(end)
    while(!S.isEmpty)
        end=S.pop()
        start=S.pop()
        q=partition(A,start,end)
        if(start<q-1)
            S.push(start)
            S.push(q-1)
        if(end>q+1)
            S.push(q+1)
            S.push(end)

三、代码实现

3.1 递归

public static void quickSort(int[] array,int p,int r){
        //p95
        if(p<r){
            int q=partition(array,p,r);
            quickSort(array,p,q-1);
            quickSort(array,q+1,r);
        }
    }

public static int partition(int[] array,int p,int r){
        //p95
        int x=array[r];
        int i=p-1;
        for(int j=p;j<r;j++){
            if(array[j]<=x){
                i+=1;
                int temp=array[i];
                array[i]=array[j];
                array[j]=temp;
            }
        }
        i+=1;
        array[r]=array[i];
        array[i]=x;
        return i;

    }

时间复杂度 O(nlgn)
空间复杂度 原址排序,递归调用需要辅助空间

3.2 非递归

public static void loopQuickSort(int[] array){
        //p95
        Stack<Integer> s=new Stack<Integer>();
        int start=0;
        int end=array.length-1;
        s.push(start);
        s.push(end);
        while(!s.isEmpty()){
            end=s.pop();
            start=s.pop();
            int q=partition(array,start,end);
            if(start<q-1){
                s.push(start);
                s.push(q-1);
            }
            if(end>q+1){
                s.push(q+1);
                s.push(end);
            }
        }
    }

public static int partition(int[] array,int p,int r){
        //p95
        int x=array[r];
        int i=p-1;
        for(int j=p;j<r;j++){
            if(array[j]<=x){
                i+=1;
                int temp=array[i];
                array[i]=array[j];
                array[j]=temp;
            }
        }
        i+=1;
        array[r]=array[i];
        array[i]=x;
        return i;

    }

时间复杂度O(nlgn)
空间复杂度:需要一个栈辅助

四、注意事项

1、快速排序每一次循环可以至少确定一个元素的位置
2、快速排序的非递归不一定比递归快
3、当需要排序的序列中有大量的相等的元素时,用快速排序性能尚可,但还有很大的改进空间,可以设计算法,将序列分成三部分,第一部分和第三部分和之前一样,第二部分存放和主元相同的元素,之后的比较只用在第一和第三部分进行。

面试准备之常见排序算法的总结!

1.插入排序   1.1直接插入排序       这是一种最简单,最容易理解的排序方式,其排序思路如下:假设待排序数组为R[0,1,2,i...n],首先将R[0]看作一个有序的子序列(尽管它只有一个...
  • kkkkkxiaofei
  • kkkkkxiaofei
  • 2014-03-20 11:54:30
  • 6405

《大话数据结构》常见排序算法总结(一)

简单排序算法 冒泡算法 初级冒泡算法 冒泡排序优化 简单选择排序 直接插入排序算法 改进排序算法 希尔排序算法 堆排序 实现步骤 归并排序 递归实现归并排序 非递归方式实现归并排序...
  • lutianfeiml
  • lutianfeiml
  • 2016-07-06 22:19:25
  • 2525

数据结构中的7种排序算法

数据结构中的7种排序算法排序是将一个记录的任意序列重新排列成一个按键值有序的序列。 时间复杂度主要考虑元素的移动次数。 结构如下: 1.直接插入排序 1,定义:依次将待排序序列中的每一个记录...
  • Decorator2015
  • Decorator2015
  • 2016-03-31 16:12:23
  • 1422

排序算法总结(6)——快速排序

通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。...
  • kakascx
  • kakascx
  • 2016-06-19 17:15:44
  • 164

十种常见的排序算法总结(java版)

排序是程序开发中非常常见的操作,对一组任意的数据元素经过排序操作后,就可以把他们变成一组一定规则排序的有序序列。排序算法属于算法中的一种,而且是覆盖范围极小的一种,但彻底掌握排序算法对程序开发是有很大...
  • canot
  • canot
  • 2016-03-06 23:03:54
  • 3339

常见排序算法(三)(快速排序、归并排序、计数排序)

本文介绍排序算法中的快速排序、归并排序、计数排序,并对每种排序算法进行了分析,附带java实现代码。...
  • sysukehan
  • sysukehan
  • 2016-09-25 14:45:19
  • 2295

【PHP-排序算法】快速排序、堆排序算法时间复杂度比较

介绍 在以往工作或者面试的时候常会碰到一个问题,如何实现海量TopN,就是在一个非常大的结果集里面快速找到最大的前10或前100个数,同时要保证内存和速度的效率,我们可能第一个想法就是利用排序,...
  • qq_28194557
  • qq_28194557
  • 2017-05-05 15:38:38
  • 1052

[数据结构]七种排序算法小结

冒泡排序 选择排序 插入排序 归并排序 快速排序 堆排序 希尔排序眼看着就要实习,为了巩固基础,回顾并总结排序算法。参考自:http://www.nowcoder.com/courses/1/1/1冒...
  • u010536377
  • u010536377
  • 2016-02-20 12:21:15
  • 2728

Objective-C实现常用的4种排序算法

OC实现的4种排序又来了,
  • u011619283
  • u011619283
  • 2014-04-17 15:14:17
  • 7214

【图解算法】排序算法——快速排序

简介 首先还是得简单的介绍一下快速排序这个算法。 快速排序(Quicksort),又称划分交换排序(partition-exchange sort),一种排序算法,最早由东尼·霍尔提出。在平均状况...
  • xiaoping0915
  • xiaoping0915
  • 2017-06-13 19:25:10
  • 3070
收藏助手
不良信息举报
您举报文章:排序算法总结(6)--快速排序
举报原因:
原因补充:

(最多只允许输入30个字)