深入解析快速排序算法的原理及其Go语言版实现_Golang

快速排序是一种基于分治技术的重要排序算法。不像归并排序是按照元素在数组中的位置对它们进行划分,快速排序按照元素的值对它们进行划分。具体来说,它对给定数组中的元素进行重新排列,以得到一个快速排序的分区。在一个分区中,所有在s下标之前的元素都小于等于A[s],所有在s下标之后的元素都大于等于A[s]。

显然,建立了一个分区以后,A[s]已经位于它在有序数组中的最终位置,接下来我们可以继续对A[s]前和A[s]后的子数组分别进行排序(使用同样的方法)。
为了排序一个数组A的全部元素,初始调用的是QUICKSORT(A,1,A.length)。

下面的算法对A[p..r]进行分区(先伪代码一下、领会意思)。

PARTITION(A,p,r)

 x = A[r]

 i = p - 1

 for j = p to r - 1

  if A[j] ≤ x

   i = i + 1

   exchange A[i] with A[j]

 exchange A[i+1] with A[r]

 return i+1

快速排序算法的效率:

在最优情况下,键值比较的次数Cbest(n)满足下面的递推式:

当n>1时,Cbest(n)=2Cbest(n/2)+n,Cbest(1)=0

根据主定理,Cbest(n)∈Θ(nlogn);对于n=2k的情况求得Cbest(n) = nlog(n)。

在最差的情况下,所有的分裂点都趋于极端:两个子数组有一个为空,而另一个子数组仅仅比被分区的数组少一个元素。具体来说,这种令人遗憾的情况会发生在升序的数组上,也就是说输入的数组已经被排过序了。所以,在进行了n+1次比较之后建立了分区,并且将A[0]和它本身进行了交换以后,快速排序算法还会对严格递增的数组A[1..n-1]进行排序。对规模减小了的严格递增数组的排序会一直继续到最后一个子数组A[n-2..n-1]。这种情况下,键值比较的总次数应该等于:

Cworst(n)=(n+1)+n+...+3=(n+1)(n+2)/2-3∈Θ(n2)

现在,轮到讨论快速排序在平均情况下的效率了。对于大小为n的随机排列的数组,快速排序的平均键值比较次数记为Cavg(n)。假设分区的分裂点s(0≤s≤n-1)位于每个位置的概率都是1/n,我们得到下面的递推关系式:

Cavg(0)=0,Cavg(1)=0

Cavg(n)≈2nlnn≈1.38nlogn
因此,快速排序在平均情况下,仅比最优情况多执行38%的比较操作。此外,它的最内层循环效率非常高,使得在处理随机排列的数组时,速度要比归并排序快。

以下是快速排序的Go代码:

复制代码 代码如下:

func QuickSort(slice_arg []int, iLeft int, iRight int) {
    if iLeft < iRight {
        var iTmpVal = slice_arg[iLeft]
        var i, j = iLeft, iRight
        for i < j {
            fmt.Println("i,j = ", i, j)
            for i < j && slice_arg[j] > iTmpVal {
                j--
            }
            if i < j {
                slice_arg[i] = slice_arg[j]
                i++
            }

            for i < j && slice_arg[i] < iTmpVal {
                i++
            }
            if i < j {
                slice_arg[j] = slice_arg[i]
                j--
            }
        }
        slice_arg[i] = iTmpVal

        QuickSort(slice_arg, iLeft, i-1)
        QuickSort(slice_arg, j+1, iRight)
    }
}

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索快速排序
, go
, go语言
golang
golang 排序算法、冒泡排序算法解析、深入学习golang、golang 深入、golang 排序,以便于您获取更多的相关知识。

时间: 2024-09-12 17:58:49

深入解析快速排序算法的原理及其Go语言版实现_Golang的相关文章

常用排序算法整理分享(快速排序算法、希尔排序)_C 语言

整理了几个排序算法,通过测试来看,最快的还是快速排序算法,简直不是一个数量级的速度. 复制代码 代码如下: #include <stdio.h>#include <stdlib.h>#include <stdint.h>#include <stdbool.h>#include <time.h>#include <unistd.h> //一些排序算法整理//插入排序算法//直接插入排序voiddirect_insert_sort(int

桶排序算法的理解及C语言版代码示例_C 语言

理解:桶排序是计数排序的变种,把计数排序中相邻的m个"小桶"放到一个"大桶"中,在分完桶后,对每个桶进行排序(一般用快排),然后合并成最后的结果.基本思想:桶排序假设序列由一个随机过程产生,该过程将元素均匀而独立地分布在区间[0,1)上.我们把区间[0,1)划分成n个相同大小的子区间,称为桶.将n个记录分布到各个桶中去.如果有多于一个记录分到同一个桶中,需要进行桶内排序.最后依次把各个桶中的记录列出来记得到有序序列.效率分析:桶排序的平均时间复杂度为线性的O(N+C

c语言快速排序算法示例代码分享_C 语言

步骤为:1.从数列中挑出一个元素,称为 "基准"(pivot);2.重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边).在这个分区退出之后,该基准就处于数列的中间位置.这个称为分区(partition)操作.3.递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序.递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了.虽然一直递归下去,但是这个算法总会退出,因为在每次的迭代(iterat

采用部分快速排序算法实现数组的部分排序

快速排序算法,网上相关文章已经介绍的很多了,数据结构教材中也有很详 细的介绍.本文需要阐述的不是全排序快速排序算法,而是部分快速排序算法. 所谓部分快速排序算法是指通过排序获取一个数列中最大的若干条有序记录.比如我们需要从一个有1百万记录的数组中获取前100条有序记录,并按从大到小顺 序显示给用户,这种应用在搜索引擎中经常被使用,很少会有人有耐心将100万 条搜索出来的记录都阅读一遍,一般阅读前几百条纪录就可以得到自己满意的答案.其实这种算法很像SQLSERVER 中的TOP n 的实现,不过数

ERLANG实现快速排序算法

问题描述 快速排序算法的思路:就是选择一个数,将比它小的放到它的一侧,比它大的放到另外一侧;然后将两侧继续递归下去按照这个方法进行排序直到排序完成.这里演示的是ERLANG的列表解析用法.然后来整理下几个语法特性-export().这个表示导出myqsort函数,然后有一个参数.这个L是一个列表X来自于列表,然后X要满足X < T这个数才能放进这个列表.-module(lib_misc).-export(). myqsort([]) -> [];myqsort() -> myqsort(

图文讲解Java中实现quickSort快速排序算法的方法_java

相对冒泡排序.选择排序等算法而言,快速排序的具体算法原理及实现有一定的难度.为了更好地理解快速排序,我们仍然以举例说明的形式来详细描述快速排序的算法原理.在前面的排序算法中,我们以5名运动员的身高排序问题为例进行讲解,为了更好地体现快速排序的特点,这里我们再额外添加3名运动员.实例中的8名运动员及其身高信息详细如下(F.G.H为新增的运动员): A(181).B(169).C(187).D(172).E(163).F(191).G(189).H(182) 在前面的排序算法中,这些排序都是由教练主

快速排序算法-C语言实现

注:本篇内容为翻译,之所以选择这篇进行翻译原因是该文章含有动画,能够更加直观地展示快速排序.同时,可以仔细看一下代码,代码中把结构化的思想给予了更加充分地表现.按照功能进行模块划分的思想得到了彻底地贯彻.   以下内容翻译自:   http://cprogramminglanguage.net/quicksort-algorithm-c-source-code.aspx     译文: 在快速排序算法中,使用了分治策略.首先把序列分成两个子序列,递归地对子序列进行排序,直到整个序列排序结束.  

如何实现快速排序算法

快速排序: 代码: <?php /** 快速排序算法 * 1. 在数组中找一个元素作为key,一般取数组第一个元素作为key * 2. i=0, j=数组长度-1 * 3. j-- 当 arr[j]<key, arr[i]与arr[j]交换位置 * 4. i++ 当 arr[i]>key, arr[i]与arr[j]交换位置 * 5. 重复3,4 直到 i==j 时,完成. * 6. 将key分隔的左右两组元素再分别执行 1,2,3,4,5 (递归). */ $arr = array()

快速排序算法的C++实现

快速排序基本特性 时间复杂度:O(n*lgn) 最坏:O(n^2) 空间复杂度:最好情况下:O(lgn),最坏情况:O(n),平均情况:O(lgn) 不稳定. 关于快速排序的空间复杂度,谢谢@命运他爹 同学指正.详述一下. 快速排序由于每次递归的时候会占用一个空间返回中间数位置,所以一次递归的空间复杂度为O(1). 最好情况和最坏情况下的递归深度为O(lgn),相应的空间复杂度就是O(lgn) 最坏情况下的递归深度为O(n),空间复杂度为O(n). 算法 QUICKSORT(A, p, r) i