天天看点

解析快速排序算法快速排序算法

快速排序算法

快速排序采用了分治法:我自己随机给出一个数组为例arr = {4,8,6,7,2,0,9,1,3,5}
           

    a.首先选定数组的第一个数作为基准数,即arr[0] = 4为初始基准数。

    b.然后给出两个初始参数i和j分别指向arr[1]和arr[arr.length-1],即初始化i=1;j=arr.length-1。

    c.指向完成后j先从右向左移动,即j- -,直到找到一个数小于初始基准数arr[0] = 4。

    d.然后i开始从左向右移动,即i++,直到找到一个数大于初始基准数arr[0] = 4。

    e.此时并不能急于交换arr[i]和arr[j]的值,而是先要判断j<=i是否成立,若成立则证明arr[0]右侧的数值都比arr[0]大,这时就需要重新划基准数(随机在数组重找一个)············重复上述过程(在此没有出现这种情况),若j>i,则arr[i]和arr[j]交换位置:

解析快速排序算法快速排序算法

    此时数组变为:4 3 6 7 2 0 9 1 8 5

    f.重复上述c d e过程。值得注意的是,i和j从交换完成的位置继续分别向右向左行进,并不是从初始位置行进。

解析快速排序算法快速排序算法

    此时数组变为:4 3 1 7 2 0 9 6 8 5

    g.以此类推:

解析快速排序算法快速排序算法

    此时数组变为:4 3 1 0 2 7 9 6 8 5

解析快速排序算法快速排序算法

    到此,发现i = j,这可如何是好?莫慌,看上述e步骤,该arr[0]和arr[j]交换的时候了,数组变为:2 3 1 0 4 7 9 6 8 5

    到这里,我们发现4左边的数全都比4小,右边的数全都比4大,这就是典型的分治法,分开治理嘛。

    h.我们此时得到的数组就可以分开治理啦,4左边的数和右边的数我们可以分别看做一个数组,然后结合递归的思想将数组arrLeft = {2,3,1,0}重复上述步骤,同样的结合递归的思想将arrRight = {7,9,6,8,5}重复上述过程,这样最终就会的道一个完整的有序数组。

解析快速排序算法快速排序算法

-----有关快速排序的时间复杂度的问题:快速排序运用了递归的思想,递归的时间复杂度为:T[n]=aT[n/b]+f(n) 。快排的时间复杂度有最优性和最差性,这和选取的初始基准数有关。

①最优情况下的时间复杂度:

    快速排序最优的情况就是每一次取到的元素都刚好平分整个数组,此时的时间复杂度公式则为:T[n] = 2T[n/2] + f(n);T[n/2]为平分后的子数组的时间复杂度,f[n] 为平分这个数组时所花的时间。

    m递归之后,n = n/( 2^(m-1) ) = 2^m T[1] + mn

得到T[n/ (2^m) ] = T[1] —》 n = 2^m —》 m = logn

    T[n] = 2^m T[1] + mn ;其中m = logn

    所以T[n] = 2^(logn) T[1] + nlogn = n T[1] + nlogn = n + nlogn(其中n为元素个数)

    当n>=2是nlogn>>n可记为T[n] = nlogn

    所以最优快速排序的时间复杂度为O(nlogn)

②最差情况下的时间复杂度:

    最差的情况下发现一个有意思的事情,排序方式竟然就是冒泡排序!!!

    T[n] = n*(n+1) = n^2+n

    此时时间复杂度为O(n^2)

-----有关快速排序的空间复杂度的问题:由于运用了递归的思想,真正消耗空间的其实是递归,快速排序使用的空间仅仅是一次即O(1)。

①最优情况下的空间复杂度:每次都均分数组O(logn)

②最差情况下的时间复杂度:冒泡排序O(n)

继续阅读