Web开发中的排序方法有哪些例子?

时间:2016-09-29 02:03:59

标签: sorting

我是算法类的TA,我们正在进行排序,我想讨论quicksort。关于网上排序方法有很多很好的理论讨论,说明哪种方法在哪种情况下更好......

我可以给学生一些快速排序的真实例子。特别是在Web开发领域。

  • Django使用快速排序吗?
  • 做了React吗?
  • Leaflet是否使用任何种类?

事实上,我并不特别关心quicksort。如果我可以指向使用它的特定库,任何排序方法都可以。感谢。

3 个答案:

答案 0 :(得分:1)

几乎所有表都已排序。大多数Web应用程序都由SQL数据库支持,实际的排序是在SQL数据库中执行的。例如SQL查询SELECT id, date, total FROM orders ORDER BY date DESC。这种排序使用已排序的数据库索引,这些索引主要使用B树(或受B树启发的数据结构)实现。但是如果数据需要动态排序,那么我认为通常会使用快速排序。

排序,合并排序文件和分类文件中的二进制搜索通常用于大数据处理,分析,广告调度,全文搜索......甚至Google结果排序:)

有时你不需要排序,但需要部分排序或小堆。例如,在Dijkstra的寻找最短路径的算法中。用于(或可以使用,或者我会使用它:))例如在路线规划(谷歌地图)中。

答案 1 :(得分:1)

  

为什么我的学生要学习排序?为什么我教这个?我可以想到学术或理论上的原因......基本上我们不断地订购东西 - 无论是本身还是作为另一种算法的一部分。对于那些可能永远不必编写自己的排序功能的学生来说怎么样?

我将回答问题" 为什么我们要学习如何编写排序函数?"为什么我们要学会写一些图书馆已经给我们的东西?哈希,列表,队列,树......为什么学会写任何一个?

最重要的是要了解他们的表现后果以及何时使用哪一个。例如,Ruby Arrays提供了许多内置功能。他们做得很好,易于使用,很容易忘记你正在使用清单并为自己写一堆糖蜜。

看看这个循环,它在列表中找到一个东西并替换它。

things.each { |thing|
    idx = thing.index(marker)
    thing[idx] = stuff
}

不了解似乎完全合理的基础算法。

  • 对于事物列表中的每个列表。
    1. 找到要替换的项目。
    2. 在其位置插入新项目。

每件事两步。什么可以更简单?当他们使用少量测试数据运行它时,它很好。当他们用一定数量的数据投入生产并且必须每秒数千次这样做时,它的狗会变慢。为什么?如果不了解所有这些方法在幕后做什么,他们就无法知道。

things.each { |thing|            # O(things)
    idx = thing.index(marker)      # O(thing)
    thing[idx] = stuff             # O(1)
}

那些看起来很简单的Array方法是他们自己的隐藏循环。在最坏的情况下,每个人都必须扫描整个列表。循环中的循环使得指数缓慢,它是O(n * m)。多慢?如果物品长达1000件,每件物品中有1000件物品...... 1000 * 1000或1,000,000件操作!

这几乎不是学生可以遇到的麻烦,通常他们会写O(n!)循环。我实际上很难想出一个我根深蒂固的例子。

但是只有之后才会显得很明显。在你写作的时候,你怎么知道?

他们如何让它更快?如果不了解你可以使用的其他选项及其性能特征,比如哈希,集合和树,他们就无法知道。经验丰富的程序员会立即对数据结构进行更改,并将things更改为sets列表。

things.each { |thing|    # O(things)
    thing.delete(marker)   # O(1)
    thing.add(stuff)       # O(1)
}

这要快得多。删除和添加无序集是O(1),因此无论thing有多大,它都是有效的。现在,如果things长度为1000个项目,并且每个thing中有1000个项目,那就是1000个操作。通过使用更合适的数据结构,我只需将该循环加速1000次。我真的把它从O(n * m)改为O(n)。

另一个可靠的例子是学习如何为多级数据编写可靠的比较函数。为什么Schwartzian transform速度快?如果不了解排序的工作原理,你就无法理解。

你可以简单地告诉他们这些事情,排序是O(n log n),在列表中找到的东西是O(n),等等......但是必须自己做这件事会让你对什么& #39;在引擎盖下进行。它让你欣赏现代语言为你所做的所有工作。

那就是说, 在编写六种不同的排序算法 ,或四种不同的树,或五种不同的哈希冲突解决功能时,没有什么意义。写下其中一个来欣赏它们,然后只是了解其余部分,以便了解它们的存在以及何时使用它们。 98%的时间精确算法并不重要,但有时候知道合并排序可能比快速排序更好。

老实说, 你永远不会写自己的排序功能 。还是树。或哈希。或排队。如果你这样做,你可能不应该。除非您打算成为编写底层库的1%(就像我一样),如果您只是要编写Web应用程序和业务逻辑,那么您就不需要全面的计算机科学教育。花时间学习软件工程:测试,要求,估计,可读性,通信等......

所以,当一个学生问及"为什么我们学习这些东西时,它们现在都已经融入了语言?" ("当我有一个计算器时,为什么我必须学习数学?")让他们用他们喜欢的方法写出他们的天真循环。把大数据推到一边,看着它慢慢爬行。然后编写一个有效的循环,其中包含良好的数据结构和算法选择,并显示它如何通过数据进行尖叫。这是他们的答案。

注意:这是在理解问题之前的原始答案。

大多数现代语言都使用quicksort作为默认排序,但通常会进行修改以避免出现O(n ^ 2)最坏的情况。这是关于qsort_r()实施的BSD手册页。 Ruby使用qsort_r

  

qsort()和qsort_r()函数是C.A.R的实现。 Hoare的“快速排行”''算法,分区交换排序的一种变体;尤其见D.E. Knuth的算法问:Quicksort的平均时间为N N lg。该实现使用中值选择来避免其O N ** 2最坏情况行为。

PHP也使用quicksort,但我不知道哪个特定的实现。

Perl默认使用its own implementation of quicksort。但您也可以通过sort pragma请求合并排序。

  

在Perl 5.6及更早版本中,quicksort算法用于实现" sort()",但在Perl 5.8中,还提供了mergesort算法,主要是为了保证最坏情况O(N log N) )行为:快速排序的最坏情况是O(N ** 2)。在Perl 5.8及更高版本中,quicksort通过在排序之前对大型数组进行混洗来防御二次行为。

Python 2.3使用Timsort并保证稳定。任何用Python编写的软件(Django)都可能使用默认的Timsort。

Javascript,实际上是ECMAScript规范,没有说明Array.prototype.sort使用什么类型的排序算法。它只表示它不能保证稳定。这意味着特定的排序算法留给了Javascript实现。与Python一样,任何Javascript框架(如React或Leaflet)都可能使用内置排序。

Visual Basic for Applications(VBA)附带NO排序算法。 You have to write your own。这对任何语言都是一种奇怪的疏忽,尤其是那些专为商业用途和电子表格而设计的语言。

答案 2 :(得分:0)

正如Schwern所指出的那样,排序几乎总是由编程语言或其实现引擎提供,而库/框架只是使用该算法,当需要对复杂对象进行排序时使用自定义比较函数。

现在,如果您的目标是在Web上下文中有一个真实的例子,那么您实际上可以使用SVG中的“缺乏”排序方法,并从中进行练习。与其他DOM元素不同,SVG容器按其附加顺序绘制其子项,而不管任何“z-index”等效项。因此,要实现“z-index”功能,您必须自己重新排序节点。

为了避免仅使用自定义比较函数并依赖array.sort,您可以添加额外的约束,例如稳定性,通常用于保留具有相同“z-index”的节点的当前顺序。

既然你提到Leaflet,那么前1.0版本(例如0.7.7)的挫折之一就是所有的矢量形状被附加到同一个SVG容器中,没有任何提供的排序功能,除了{{1} } / bringToFront