• 递归优化之快速排序


    很多人都说.net排序的效率高,抱着学习的态度观摩.net源代码。当数据类型为基本类型并且未指定排序规则时用的是本地代码(TrySZSort),否则使用快速排序的泛型实现。

    QuickSort

    经测试TrySZSort的运行时间为快速排序泛型实现的1/2左右,据推测TrySZSort与QuickSort采用的是同样的算法,不过TrySZSort的实现是本地代码的指针模式。快速排序是我所知道的通用排序方法当中实际平均运行效率最高的,平均时间复杂度为O(n*log(n)),当然最坏情况可能是O(n^2),但是这种概率也是指数级的。
    很多人实现的快速排序都有一个致命缺陷,那就是没有控制递归深度,等于给自己埋了个地雷。我们知道快速排序每一个循环都会把数据分成两段,QuickSort采用双重循环,只递归数量少的一段,另一段继续循环,这样就把递归深度控制在log(N)之内,完美的实现了排雷处理。


    QuickSort的实现真的很棒,但是在递归过程中却做了一些无用功,可以看到T[] keys与IComparer<T> comparer这俩一直就没变过,却被不停的传来传去。既然发现问题,那就解决它。

    Sort

    参考QuickSort主要修改了一下递归传参部分,Release实测运行时间降到QuickSort的80%,可以说QuickSort做了20%无用功。测试数据为100000000个随机整数。

    下面用同样的方式来模拟TrySZSort。

    Sort

    Release实测,运行时间为TrySZSort的90%,效果不够理想,我们再把intSorter改为指针模式。

    Sort<int*>

    Release实测,运行时间为TrySZSort的80%,所以我猜测TrySZSort与QuickSort使用的是同样的算法。

    有时候我们需要对数据进行分页取其中一页,这时候就没必要把所用数据都排好序,这个时候需要对排序程序做一些修改。

    RangeSort

    其实我这里要说的重点不是快速排序,而是借快速排序的实现说递归优化,不知你是否看明白了,因为递归也是很常用的。
    快速排序在不同的场合还有不同的优化方法,比如对于较大的结构体可以创建一个用于排序的索引数组,比如对于排序字段计算复杂的可以创建一个用于排序的缓存值数组,比如数据段小于8的时候采用硬编码方式。

     
  • 相关阅读:
    beego 注解路由无效问题分析
    sync.Map实现分析
    由浅入深聊聊Golang的sync.Map
    Go语言编程:使用条件变量Cond和channel通道实现多个生产者和消费者模型
    golang 的 channel 实现 生产者/消费者 模型
    Golang sync.NewCond条件锁的用法
    golang channel多生产者和多消费者实例
    Go语言的那些坑
    go语言标准库sync/atomic中的原子操作
    理解 Go 标准库中的 atomic.Value 类型
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2496193.html
Copyright © 2020-2023  润新知