排序算法之快速排序

来源:互联网 发布:正元软件 编辑:程序博客网 时间:2024/06/07 16:42

快速排序:其根本思想是基于分治法的,每次从待排序的序列中找出一个数记为p,将序列中所有比p大的数字放在p后面,将所有比p小的数放在p前面,再对p左右两边的子序列执行上述操作,直到子序列的长度为1(一个数一定有序),最后返回的序列就是有序序列。


快排相关:

  • 空间复杂度:因为快排是基于递归的,所以需要一个递归栈来保存每层的调用信息,平均情况为O(logn),最差的情况下为O(n)
  • 时间复杂度:当原始序列基本有序或逆序时,时间复杂度为 O(N^2),正常情况下的时间复杂度为O(nlogn)

关于快排的实现方式我们可以这样理解:

  1. 得到一个p(通常直接取序列的第一个元素)
  2. 从序列的最后位置向前遍历,直到找到一个比p小的数,记下当前数的位置
  3. 从序列的最开始位置向后遍历,直到找到一个比p大的数,记下当前数的位置
  4. 将两个数交换位置
  5. 重复上述2,3,4步,直到p前面的数都小于p,p后面的数都大于p
  6. 对p的左右子序列分别进行上述2,3,4,5操作
  7. 最后得到有序序列

因为没有图片的缘故,只看文字可能不好理解,建议结合代码反复看一看
快排的第一种实现:

public static int  qsort(int a[], int l, int r) {        int i=l, j=r;        int x = a[i];        //2,6,4,3,1,5        while(i < j) {            while(i < j && a[j] >= x) {                j--;            }            if(i < j) {                a[i] = a[j];            }            while(i < j && a[i] < x) {                i++;            }            if(i < j) {                a[j] = a[i];            }        }        a[i] = x;        return i;    }    public static void partition(int a[], int l, int r) {        if(l < r) {            int part = qsort(a, l, r);            partition(a, l, part-1);            partition(a, part+1, r);        }    }

我们可以看到qsort方法来执行一次对一个数左右子序列的处理,partition方法用于处理qosrt方法的子序列

快排也可以只用一个方法来递归完成:

public static void qsort2(int[] a, int l, int r) {        if(l < r) {            int i=l, j=r;            int x = a[i];            while(i < j) {                while(i < j && a[j] >= x) {                    j--;                }                a[i] = a[j];                while(i < j && a[i] < x) {                    i++;                }                a[j] = a[i];            }            a[i] = x;            qsort2(a, l, i-1);            qsort2(a, i+1, r);        }    }

测试代码:

public static void main(String[] args) {        int a[] = new int[]{2,6,4,3,1,5};        qsort2(a, 0, a.length-1);        for(int i : a) {            System.err.print(i + ",");        }    }

测试结果:

[1, 2, 3, 4, 5, 6]
0 0
原创粉丝点击