`
JhonStryker
  • 浏览: 19540 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

网上的一篇关于sort()方法的分析

阅读更多

原文地址:http://blog.donews.com/maverick/archive/2006/07/09/951101.aspx

 

Python语言内置了sort方法,可以很方便地对某个List进行排序:
L = [6, 5, 1, 3, 4, 2]
L.sort()
print L

———- Run Python Program ———-
[1, 2, 3, 4, 5, 6]

某些时候,我们希望按照自己定义的排序规则来排序(例如,按关键词的权重排序,按人的年龄排序,等等)。在Java语言中,我们可以自定义Comparator来实现,Python中也提供了类似的办法。

若List中每个元素都是2-tuple,tuple中第一个元素为String类型的keyword,第二个元素为该字符串对应的权重(int类型),希望按照权重排序(从高到低),则可以这样:
def my_cmp(E1, E2):
    return -cmp(E1[1], E2[1])    #compare weight of each 2-tuple
                    #return the negative result of built-in cmp function
                    #thus we get the descend order

L = [('a', 0), ('b', 1), ('c', 2), ('d', 3)]
L.sort(my_cmp)
print L

———- Run Python Program ———-
[('d', 3), ('c', 2), ('b', 1), ('a', 0)]

正因为可以自定义cmp方法,我们不妨探究一下,built-in的sort方法,到底是采用的哪一种排序算法:
from random import shuffle

def my_cmp(E1, E2):
    print ‘E1:’, E1, ‘E2:’, E2
    return cmp(E1, E2)

L = range(0, 10)
shuffle(L)
print L
L.sort(my_cmp)

———- Run Python Program ———-
[5, 3, 7, 6, 2, 8, 9, 4, 1, 0]
E1: 3 E2: 5
E1: 7 E2: 3
E1: 7 E2: 5
E1: 6 E2: 5
E1: 6 E2: 7
E1: 2 E2: 6
E1: 2 E2: 5
E1: 2 E2: 3
E1: 8 E2: 5
E1: 8 E2: 7
E1: 9 E2: 6
E1: 9 E2: 8
E1: 4 E2: 6
E1: 4 E2: 3
E1: 4 E2: 5
E1: 1 E2: 6
E1: 1 E2: 4
E1: 1 E2: 3
E1: 1 E2: 2
E1: 0 E2: 5
E1: 0 E2: 3
E1: 0 E2: 2
E1: 0 E2: 1

可以看到,每次调用my_cmp,E1依次是List中的第2、3、4……直到最后一个元素,可以肯定sort不是采用的分治法(devide-and-conqure)
看前三次调用,可以发现sort采用的是典型的插入排序——也就是说,将新元素插入已排序部分的合适位置,查找位置时采用的似乎是从后向前线形探察的办法。从元素6开始,新元素不再直接与已排序部分的最后元素比较,而是先与中间值比较,采用二分检索探察合适位置,这样,可以把时间代价从n缩小到log(n)。
至此,我们可以认为,built-in的sort方法,采用的是“二分法插入排序”(binary insertion)的算法。

为了检测这个结论,可以输入一个已排序的数组,看看结果。
L = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
L.sort(my_cmp)

———- Run Python Program ———-
E1: 1 E2: 0
E1: 2 E2: 1
E1: 3 E2: 2
E1: 4 E2: 3
E1: 5 E2: 4
E1: 6 E2: 5
E1: 7 E2: 6
E1: 8 E2: 7
E1: 9 E2: 8
E1: 10 E2: 9

结果发现,比较的次数非常少,插入每个元素的时候,只会与它之前紧邻的元素比较,而不是二分检索。这真是个有意思的现象。

改一改程序
L = [0, 1, 2, 3, 4, 5, 6, 8, 7, 9, 10]
L.sort(my_cmp)

———- Run Python Program ———-
E1: 1 E2: 0
E1: 2 E2: 1
E1: 3 E2: 2
E1: 4 E2: 3
E1: 5 E2: 4
E1: 6 E2: 5
E1: 8 E2: 6
E1: 7 E2: 8
E1: 7 E2: 4
E1: 7 E2: 6
E1: 7 E2: 8
E1: 9 E2: 4
E1: 9 E2: 7
E1: 9 E2: 8
E1: 10 E2: 5
E1: 10 E2: 8
E1: 10 E2: 9

可以看到,在数字8以前,List中的元素都是有序的,于是sort算法也只比较欲插入元素和已排序序列的最后一个元素;一旦发现输入序列不是自然有序之后,就采用二分插入排序算法。
这样的混合排序算法,相对单纯的插入排序,保证了最好条件下时间代价最低,也减小了一般情况下的时间代价。

p.s.
写完之后查阅Python的文档,发现sort采用的是混合(hybrid)排序,规模小的时候采用binary insertion,规模大的时候采用samplesort(据说是quicksort的一个变种,我没接触过,汗….)

分享到:
评论

相关推荐

    python sort、sort_index方法代码实例

    本篇文章将详细解释`sort`和`sort_index`这两个方法,并通过具体的代码示例来展示它们的用法。 #### 一、`sort`方法简介 在Pandas中,`sort`方法主要用于对DataFrame或Series对象进行排序。它支持按照值或索引进行...

    基于深度学习的视频全量分析方法.pdf

    《基于深度学习的视频全量分析方法》这篇文章探讨了如何运用深度学习技术对高清视频进行全方位分析,尤其针对街景内容。文章的核心在于目标检测、多目标追踪和全景分割的结合,以解决视频分析中的关键问题。 首先,...

    08-排序5. Sort with Swap(0) (25).zip

    Sort with Swap(0) (25).zip"表明这是一个关于排序算法的专题,特别是涉及到不使用交换操作(swap)的排序方法。在计算机科学中,排序是将一个数据序列按照特定顺序进行排列的过程,这对于数据分析、数据库管理等...

    实证Stata代码命令汇总(可完整创作一篇实证论文).zip

    本压缩包文件“实证Stata代码命令汇总(可完整创作一篇实证论文)”显然是为了帮助用户了解如何使用Stata进行完整的实证分析,从而撰写出一篇高质量的学术论文。下面,我们将详细讨论其中可能包含的知识点。 首先,...

    统计一篇文档中每个单词出现的次数,频率

    在IT领域,文本分析是一项重要的任务,而统计文档中每个单词的出现次数是其中的基础步骤。这个过程通常称为词频统计,它可以帮助我们理解文本的主要主题、找出关键词或进行文本挖掘。下面,我们将深入探讨如何在Java...

    sort排序1

    `sort()`方法是MongoDB查询操作中的一个重要组成部分,它允许我们对查询结果进行排序,以便于数据的分析和展示。正如标题“sort排序1”和描述中所提及的,`sort()`方法可以根据一个或多个键(key)进行排序,可以是...

    STM8S003单片机数组10种排序方法分析比较

    数组排序是常见的数据处理任务,本篇文章将对在STM8S003上实现的10种排序方法进行分析和比较。 1. 冒泡排序(Bubble Sort) 冒泡排序是最基础的排序算法,通过不断交换相邻的不正确顺序元素来达到排序目的。它的...

    第3篇:Web日志分析.pdf

    ### Web日志分析知识点 #### 一、Web日志简介 - **定义**:Web日志是指由Web服务器自动生成的记录文件,其中包含了...掌握正确的分析技巧和工具运用方法,对于从事网络安全、网站开发与运维的专业人士来说至关重要。

    JS sort方法基于数组对象属性值排序

    本篇将详细介绍如何利用`sort`方法实现基于数组对象属性值的排序。 首先,`sort`方法接受一个比较函数作为参数。这个比较函数定义了如何比较数组中的两个元素。在处理对象数组时,比较函数通常会获取对象的属性值,...

    算法设计与分析-1排序算法性能分析-冒泡/选择/插入/合并/快速排序-pre ppt

    本篇文章将详细讨论几种常见的排序算法:选择排序、冒泡排序、插入排序、合并排序以及快速排序,分析它们的算法原理、时间效率,并通过经验分析验证理论分析的准确性。 **1. 选择排序(Selection Sort)** 选择排序...

    JAVA拓扑排序实现及分析

    在计算机科学中,拓扑排序是对有向无环图(DAG,Directed Acyclic Graph)进行排序的一种方法,它将图中的...以上就是关于使用Java实现拓扑排序及其分析的详细内容,希望能帮助你深入理解和掌握这一重要的图论算法。

    排序算法性能分析

    本篇文章将详细分析八种常见的排序算法,探讨它们的执行效率,以及关键语句的执行次数。 1. 冒泡排序(Bubble Sort) 冒泡排序是最基础的排序算法之一,通过不断交换相邻的逆序元素实现排序。其平均时间复杂度为O(n...

    第2篇:Linux日志分析.pdf

    - `grep "Failed password for root" /var/log/secure | awk '{print $11}' | sort | uniq -c | sort -nr | more`:统计尝试爆破root账号的IP地址次数。 通过以上介绍,我们可以看出Linux系统的日志文件及其分析...

    shuffle的关键阶段sort(Map端和Reduce端)源码分析

    shuffle 的关键阶段 sort(Map 端和 Reduce 端)源码分析 在 Hadoop 的 MapReduce 框架中,...这篇文章对 shuffle 的关键阶段 sort(Map 端和 Reduce 端)的源码进行了深入分析,帮助读者了解排序的原理和实现机制。

    使用DeepSORT对YOLOv5和YOLOv7模型进行液滴跟踪基准测试应用

    在微流体研究中,液滴的精确跟踪是至...这些发现为微流体分析提供了有价值的指导,有助于选择适合特定实验条件的工具和方法。未来的研究可能会进一步优化这种结合,以提高跟踪效率和准确性,同时降低对计算资源的需求。

    Linux文本处理命令sort详解

    本篇文章将详细介绍`sort`命令的使用方法,帮助用户更好地理解和掌握这一功能。 首先,`sort`命令的基本用法是`sort +选项 +文件名`。例如,如果你有一个名为`1.txt`的文件,你可以通过`sort 1.txt`命令将其内容按...

    java 分析英文文章,并统计每个字母出现的次数

    在Java编程语言中,分析英文文章并统计每个字母出现的次数是一项常见的文本处理任务,它涉及到字符串操作、字符计数和文件I/O等基础知识。以下是一个详细的步骤介绍和相关知识点讲解: 1. **读取文本文件**:首先,...

    C#编程-提高篇

    - **`Sort<T>`** 方法是一个泛型方法,它接受一个泛型列表`IList<T>`以及一个比较委托`Func, T, bool>`。 - **`Func, T, bool>`** 是一个预定义的委托类型,表示一个方法接受两个`T`类型的参数并返回一个布尔值。在...

    JS中sort函数排序用法实例分析

    本篇文章将深入探讨`sort()`函数的用法,并通过实例分析其工作原理。 ### `sort()`函数的基本用法 `sort()`函数默认情况下按照字符串的Unicode编码(ASCII值)进行排序,这意味着即使是数字也会被当作字符串来处理...

Global site tag (gtag.js) - Google Analytics