zoukankan      html  css  js  c++  java
  • 递归优化之快速排序

    很多人都说.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的时候采用硬编码方式。

     
  • 相关阅读:
    移动端屏幕旋转的事件和样式方案。
    active:移动端触摸按钮的效果。
    移动端字体单位该使用px还是rem?
    Cordova/Ionic Android 开发环境搭建
    JavaScript 深拷贝(deep copy)和浅拷贝(shallow copy)
    你不知道的JS之 this 和对象原型(一)this 是什么
    你不知道的JS之作用域和闭包 附录
    你不知道的JS之作用域和闭包(五)作用域闭包
    你不知道的JS之作用域和闭包(四)(声明)提升
    你不知道的JS之作用域和闭包(三)函数 vs. 块级作用域
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2496193.html
Copyright © 2011-2022 走看看