常见排序算法 - 堆排序 (Heap Sort)

算法原理

先上一张堆排序动画演示图片:

图片来自维基百科

1. 不得不说说二叉树

要了解堆首先得了解一下二叉树,在计算机科学中,二叉树是每个节点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树二叉堆

二叉树的每个结点至多只有二棵子树(不存在度大于 2 的结点),二叉树的子树有左右之分,次序不能颠倒。二叉树的第 i 层至多有 2i - 1 个结点;深度为 k 的二叉树至多有 2k - 1 个结点;对任何一棵二叉树 T,如果其终端结点数为 n0,度为 2 的结点数为 n2,则n0 = n2 + 1。

树和二叉树的三个主要差别:

  • 树的结点个数至少为 1,而二叉树的结点个数可以为 0
  • 树中结点的最大度数没有限制,而二叉树结点的最大度数为 2
  • 树的结点无左、右之分,而二叉树的结点有左、右之分

二叉树又分为完全二叉树(complete binary tree)和满二叉树(full binary tree)

满二叉树:一棵深度为 k,且有 2k - 1 个节点称之为满二叉树

深度为 3 的满二叉树 full binary tree

完全二叉树:深度为 k,有 n 个节点的二叉树,当且仅当其每一个节点都与深度为 k 的满二叉树中序号为 1 至 n 的节点对应时,称之为完全二叉树

深度为 3 的完全二叉树 complete binary tree

常见排序算法 - 选择排序 (Selection Sort)

算法原理

选择排序(Selection Sort)是一种简单直观的排序算法。它的工作原理如下,首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

选择排序的主要优点与数据移动有关。如果某个元素位于正确的最终位置上,则它不会被移动。选择排序每次交换一对元素,它们当中至少有一个将被移到其最终位置上,因此对n个元素的序列进行排序总共进行至多n-1次交换。在所有的完全依靠交换去移动元素的排序方法中,选择排序属于非常好的一种。

图片来源于维基百科

常见排序算法 - 快速排序 (Quick Sort)

算法原理

快速排序是图灵奖得主 C. R. A. Hoare 于 1960 年提出的一种划分交换排序。它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod)

C. R. A. Hoare

分治法的基本思想是:将原问题分解为若干个规模更小但结构与原问题相似的子问题。递归地解这些子问题,然后将这些子问题的解组合为原问题的解。

利用分治法可将快速排序的分为三步:

  1. 在数据集之中,选择一个元素作为”基准”(pivot)。
  2. 所有小于”基准”的元素,都移到”基准”的左边;所有大于”基准”的元素,都移到”基准”的右边。这个操作称为分区 (partition) 操作,分区操作结束后,基准元素所处的位置就是最终排序后它的位置。
  3. 对”基准”左边和右边的两个子集,不断重复第一步和第二步,直到所有子集只剩下一个元素为止。
    图片来自维基百科

常见排序算法 - 冒泡排序 (Bubble Sort)

算法原理

冒泡排序(Bubble Sort,台湾译为:泡沫排序或气泡排序)是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。

冒泡排序算法的流程如下:

  1. 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
  2. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
  3. 针对所有的元素重复以上的步骤,除了最后一个。
  4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

由于它的简洁,冒泡排序通常被用来对于程序设计入门的学生介绍算法的概念。

图片来自维基百科

JavaScript 随机打乱数组 - 洗牌算法

在学习排序算法的时候,经常要用到随机数组,于是就写了一个生成随机数组的方法。算法来自网络,只是修改成了 JavaScript 版本。

基本原理是洗牌算法,首先从所有元素中随机选取一个与第一个元素进行交换,然后在第二个之后选择一个元素与第二个交换,直到最后一个元素。这样能确保每个元素在每个位置的概率都是1/n。

具体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/**
*
* 生成从 1 到 length 之间的随机数组
*
* @length 随机数组的长度,如果未传递该参数,那么 length 为默认值 9
*
*/
function randomArray(length) {
var i,
index,
temp,
arr = [length];
length = typeof(length) === 'undefined' ? 9 : length;
for (i = 1; i <= length; i++) {
arr[i - 1] = i;
}
// 打乱数组
for (i = 1; i <= length; i++) {
// 产生从 i 到 length 之间的随机数
index = parseInt(Math.random() * (length - i)) + i;
if (index != i) {
temp = arr[i];
arr[i] = arr[index];
arr[index] = temp;
}
}
return arr;
}

浏览器背后的故事 - 浏览器内部工作原理

原文链接:How Browsers Work: Behind the scenes of modern web browsers
原文日期:2011年8月5日

序言

这是一篇全面介绍基于 Webkit 和 Gecko 内核浏览器内部原理的入门文章,是以色列开发人员 Tali Garsiel 大量研究的成果。在过去的几年中,她查阅了所有公开发布的关于浏览器内部机制的数据(请参见参考资料),并花了很多时间来研读网络浏览器的源代码。她这样写道:

在 IE 占据 90% 市场份额的年代,我们除了把浏览器当成一个“黑盒”,什么也做不了。如今,开源浏览器拥有了过半的市场份额,因此,是时候来揭开神秘的面纱,一探网络浏览器的内幕了。呃,里面只有数以百万行计的 C++ 代码 …

Tali Garsiel她的网站上公布了自己的研究成果,但是我们觉得它值得让更多的人来了解,所以我们在此重新整理并公布。

作为一名 Web 开发人员,学习浏览器的内部工作原理将有助于您作出更明智的决策,并理解那些最佳开发实践的个中缘由。尽管这是一篇相当长的文档,但是我们建议您多花一些时间来仔细阅读,读完之后,您肯定会觉得所费不虚。

Paul Irish,Chrome 浏览器开发人员事务部

Generate and Debug with Source Map

上一篇文章简单介绍了 Source Map,接下来我们来看看如何利用各种工具来生成 Source Map。

什么是 Source Map?

Source Map 提供了一个与语言无关的方式,来将生产环境中的代码映射回开发环境中的原始代码。

在现代的开发流程中,我们的开发环境和实际线上环境的代码通常都不一样。在应用上线部署前,我们通常都要对我们的代码进行编译、合并、压缩或者其他方面的优化,这使得我们非常困难来准确定位会原始代码。但是,在生成过程中,Source Map 文件储存了这些位置信息,因此,当我们查找一行中的某个位置时,Source Map 文件可以准确定位到原始文件中的位置。这使得我们线上环境中的代码变得可读,甚至可调试,为开发者提供了极大的便利。这就是 Source Map 的用武之地。

在这篇介绍性的教程中,我们利用一个非常简单的 JavaScript 和 SASS 代码,通过各种编译器运行它们,然后在 Source Map 的帮助下,在浏览器中查看我们的原始文件。文中示例代码可以在这里【下载】。

JavaScript Source Map 介绍

翻译自:Introduction to JavaScript Source Maps

水平有限,有表达错误和不准确的地方,可以在回复中直接指出来,英语水平高的同学可以直接看上面的原文。

下面开始正文。

你有没有希望保持你的客户端代码可读性,更重要的是可调式性,即使你合并和压缩过代码,同时又不影响性能?现在你可以通过 Source Maps 的魔力来实现。

从根本上说,这是一种将合并/压缩后的文件映射回未构建状态的方式。当构建产品,合并和压缩你的 JavaScript 文件的同时,生成一个包含源文件信息的 Source Maps 文件。当你查询生成后的文件中某一行号和列号的位置时,你可以通过 Source Maps 来返回它所对应的原始位置。开发人员工具(WebKit 最新版,Google Chrome,Firefox 23+)可以自动解析 Source Maps,使得看起来好像你在运行未压缩和合并的文件。

Demo: Get original location

打开上面示例的连接,在包含生成后文件的文本区域的任何地方点击鼠标右键,选择 “Get original location”,将通过生成后的文件的行号和列号查询 Source Maps,并返回原始代码的位置。确保你的控制台是打开的,这样你就可以看到输出。


那些年我使用过的 Sublime Text 3 插件

其实,我最开始接触到的是 Sublime Text 2,被其轻量、简洁以及漂亮的配色所瞬间征服,后来升级为 Sublime Text 3,使用过程中有一些需要设置的地方,还有一些常用插件的安装和设置技巧等,有时候会忘记某些设置方法或者快捷键,然后不得不上网查。恰逢周末,其中的一些东西记录下来,一方面加深自己的印象,同时方便查阅。


HTML/CSS 速写神器:Emmet

在前端开发的过程中,一个最繁琐的工作就是写 HTML、CSS 代码。数量繁多的标签、属性、尖括号、标签闭合等,让前端们甚是苦恼。于是,我向大家推荐 Emmet,它提供了一套非常简单的语法规则,书写起来非常爽快,然后只需要敲一个快捷键就立刻生成对应的 HTML 或 CSS 代码,极大提高了代码书写效率。

go2top