也谈排序算法

最近期末复习正好看到算法的分治策略,里面讲到两种排序算法:合并排序和快速排序。这里大概就谈下自己对算法的理解,代码不是最重要的,思想才是精华,所以这次不打算讲太多代码。

首先说一下分治法的基本思想,分治法是把一个规模为n的问题分解为k个规模较小的子问题,这些子问题相互独立且与原问题相同(这里需要注意分治算法与动态规划的区别)。递归地解这些子问题,然后将各子问题的解合并得到原问题的解。这里要谈到的合并排序和快速排序便是分治算法的典型应用之一。

首先看合并排序,其基本思想是将待排序元素分成大小大致相同的2个子集合,分别对2个子集合进行排序,最终讲排好序的子集合合并成为所要求的排好序的集合。算法一般通过计算两个边界的中点作为分界点,然后再递归调用对左半边和右半边分别合并排序,递归中止条件自然是左边界小于右边界,即保证至少有两个元素参与排序。当一轮调用中,左半边和右半边分别排序完成后(或无法再划分进行排序后),就进行合并,其中对元素的真正排序便是在合并中完成的,利用一个临时数组完成对排序后数组两边元素的排序、合并。如下是一个合并排序的过程图,其中S代表mergeSort函数,即递归函数,其中参数待排序数组,左分界点,右分界点;m代表merge函数,即排序、合并函数,其参数分别为待合并数组,目的合并数组,合并左分界点,合并中点,合并右分界点。

mergesort

再来看看快速排序,其基本思想是对于输入的子数组a[p:r],按以下3个步骤进行排序:

  1. 分解(divide):以a[p]为某基准元素,将a[p:r]划分成3段,a[p:q-1], a[q]和a[q+1:r],使得a[p:q-1]中的任何元素都小于等于a[q],而a[q+1:r]中的任何元素大于等于a[q],q在划分中确定;
  2. 递归求解(conquer):通过递归调用快速排序算法,分别对a[p:q-1]和a[q+1:r]进行排序;
  3. 合并(merge):由于对a[p:q-1]和a[q+1:]r的排序在分解过程中就已经完成,所以当前a[p:q-1]和a[q+1:r]中的元素都已经排好序了,无须再执行任何计算,a[p:r]就已经完成排序了。

如下以a = [5, 3, 7, 2, 6, 4, 8, 1, 9]为例,具体分析一下快速排序的过程,【】表示划分元素,{}表示需交换元素。

quicksort

由上述分别对两种算法的说明,大致也能看出两算法的异同之处。两种算法都考虑到使用划分元素的方法进行分治的依据,但合并排序的划分元素是直接去两边界的中点,而快速排序的划分点则是在排序中找到;合并排序首先进行划分,然后再对划分的部分递归调用,而快速排序则是在排序过程中找到划分点,之后再递归调用;再次,合并排序需要借助一个临时数组完成合并操作,而快速排序则不需要特别地合并操作,也无需临时数组,其排序是在划分中完成,而合并则只需简单连接即可。

虽然自己已经对上述算法有了比较具体的了解,但是要深入理解还是需要慢慢体会,领悟其中玄机,同时也需要在不参考参考程序的过程中,完成自己程序的编写,这样不但锻炼了编程能力,更加需要对算法本身有较透彻的理解,所以下一步自己需要用一门语言用自己的方法实现算法。

各个浏览器用CSS3绘制的机器猫

刚刚看到的,好有喜感了~用CSS3绘制的机器猫,唯独IE8话的那个是?!

用CSS3绘制的机器猫

猛击进入测试页面(需翻墙)

猛击进入在线多浏览器测试截图(需翻墙)

p.s.靠,怎么都要翻墙啊?!

[乐铺活动验证]

又是好久没写Blog

转眼一看上篇博客文章,又快2个月没有更新了,之前一直说要更新要更新,其实也有挺多技术文章想分享分享的,可是总是因为这样那样的原因都没来得及记录下来,真是比较惭愧啊~今天突然想想,再忙还是应该找时间来写一下啦,也算是练练手吧~之前记得看过一篇文章,上面说程序员应该具有的素质,其中一条就是说要保持写作,当然也包括写blog了,我想可能这就是要保持一种交流的能力,以及一种表达的能力吧~

前段时间说要学习PHP,后来果真就把《PHP和MYSQL WEB开发》借来看了看,到不久前,其实已经大体浏览的一遍,不过自认为实际没掌握什么,因为没有项目经历,或者说是没有更多的实践机会,所以导致很多只是在眼前飘过,但实际并未掌握~其实一直也想找机会来实践实践的,因此也想找机会做个项目试试,不过到现在还没有实际去做点儿什么 :mrgreen: 不过一直和工作室吴迪有交流,他说PHP的很多特性比较恶心,当时没在意,不过后来想想说得的确有道理,最直接的一个就是各种函数的命名就是一个巨恶心的挑战,这里就不多说了,网上已经很多对PHP的评价的文章~后来一次偶然机会看到这个分享《Python于Web 2.0网站的应用》 就对Python产生了不少兴趣,后来和BlueF聊的时候,他也推荐我去看看Python,所以就在图书馆找了《Python核心编程》来看看~说实在的,在图书馆找本Python的书好困难啊,英文原版还有些,中文的基本就没有,要么就是被借走了,现在这本也是我找好久终于在一个角落找到的哈~当时还挺兴奋的就翻了不少看看~看到前面作者有说对于JavaScript的程序员,学习Python也比较简单,所以我现在也坚定了学习Python的信念,虽然PHP还是当前WEB开发的第一语言,不过自己只想了解了解就好,对于Python还是想能够掌握得深一些更好~目前《Python核心编程》已经看了数章了,感觉还不错,觉得Python这门语言的确是很需要强调Simple的语言,它独有的强制代码缩进方式也有不少优势,而且很多特性也比较有意思,比如这个写法[2 ** x for x in range(5)],就可以简单的列举出2的0到4次方,再如(x, y) = (1, 2); (y, x) = (x, y)就能很方便的交换两个变量而不需要传统编程语言的方法,真是神奇哈~ :biggrin: 不过Python好多方式和JavaScript的确不大相同,所以在学习过程中我一定要注意和JS的对比,以便能够熟练掌握两门语言而不至于相互混淆~所以以后一定要多写写读书笔记才行啊~

接着说说JavaScript方面的事儿吧,前段时间大军让我研究研究Web编辑器的技术,后来就看到不少文章,包括Range,Selection,execCommand等技术的东东,这方面之前真的接触太少太少了,很难马上就能搞定,后来自己又大体研究了研究Kissy Editor的代码,确实有不少收获,不仅包括前面那些自己接触甚少的技术,更是包括JavaScript架构方面的概念,感觉Kissy这个框架的架构方面的确有很多先进的地方需要我去理解,同时也真的发现接触的JavaScript越来也多,自己的无知也就暴露地更加明显,尤其是架构方面的东东,真是很匮乏啊~ :sad: 再接着说,5月初的时候,有了人生第一次面试经历吧,不过是电话面试哈,面试方是百度,也颇让自己有些压力,通过面试,发现自己在基础知识方面还是有不少漏洞啊,特别是很久没写页面,很多页面相关知识也是忘记得差不多了,面试过程中很多原来了解的东东,回答过程中也答得不满意,可能由于紧张吧,不过准确地说应该是自己掌握得还不足吧,不过总的来说面试还算顺利吧,貌似要等二面~最近一段时间,由于工作室另外一个项目的原因,需要去研究研究Googe Maps API,所以最近在研究这个东东,难度不算大吧,主要是看文档和实际运用,只是很感叹Google对API的设计强大、精巧,真的很难想像这些JavaScript是怎么实现的,真是膜拜得不行了~ :razz:

那天在图书馆,还顺便借了一本《版本控制之道》在看,之前项目中一直在使用,不过里面好多特性都没有用到,这次算是借书来过一遍吧,了解了解SVN的基本特性~

差不多了,前段时间大概就这么样吧,总的来说还是很忙的,很多事儿要弄,也有很多知识自己得学,当然现在课也没逃多少,所以也就感觉比较忙啦~不过这应该就算是充实吧,希望自己在忙碌中有条不紊地进步吧~ :smile:

又回来了暨近期总结

我的这个博客真是好久好久没有更新了,昨天在工作室,弈哥居然还笑话我他都能把我博客首页的几篇文章名字倒背如流,囧了 :mrgreen: 不过话又说回来,的确,博客上最新一篇文章也都是去年5月份更新的啦,确实也快有一年时间了~现在想想这一年时间都在干嘛,博客都没更新,也该总结总结了~

那就从近期说起吧,原来博客是放在工作室买的一个空间上,不过因为和谐原因,服务器不幸倒下了,导致博客也down了好久,今年寒假回去就想折腾一下域名出国,空间出国事宜,所以索性就把这个域名从万网迁到GoDaddy.com了,虽然期间也有纠结,也花了些冤枉钱,不过最后还是顺利迁出。其实如果实在遇到万网蛮横,google一下还是不少办法的~其次就是在网上转了一段时间,物色了这个VPS(由Diahosting提供的X128)配置也倒不错,速度也行,就是一个人负担每月¥70还是感觉有点儿贵,关键是自己利用率不高~现在主要用来放这个博客,还有搭了个VPN,本来打算是多写点儿自己的项目放上面的,不过暂时没什么时间搞,所以……不过这次折腾这个VPS倒是也学到了不少,特别是Linux相关只是,只是搭建服务器还是挺简单的,直接用LNMP就可以搭建出一个PHP+NINGX+MYSQL环境,不过以后打算自己从零开始,自己手动编译来搭建一次,不过这些都是后话了~还有就是VPN也是我买VPS的一个主要原因,当前国内网络环境实在是不怎么地,所以X墙行为就是必须的了,不过之前在家用PPTP的VPN用得还挺好,速度也行,不过到学校了就不行,后来才知道是因为这边网络环境比较复杂,所以PPTP容易连接失败,后来只能换成L2TP+IPSEC来搞,不过一直搞了快2周才搞定,中间过程实在太纠结,这里就不细说了,以后再好好回忆回忆写篇文章记录一下~

再接着往前回忆,在此之前写的最新一篇文章也是大一时候写的了,自己现在都大二下了,感觉时间真是过得好快啊~从大一到大二,真是有不少变化了,既变得开始适应“科大”这种风格了,也开始变得惆怅、迷茫,身边的同学也差不多都这样吧~不过我感觉对于我来说,最大的变化就是找到了她,从那儿之后自己真的感觉变了很多很多,我想这都是很难得的收获,我会永远珍惜你,珍惜现在的一切!其他的现在一时也回想不起来了,回忆就暂时到这儿吧~

既然这次想回来继续写博客了,也应该说说自己的打算~目前学习挺紧的,哈,我都感觉这话从我嘴里说出来都不那么真实,不过这学期自己确实是这样的,不管什么原因吧,我总觉得那些学的东西对我有用,我就愿意去听听~我一直都认为只为了应试,那么每科一周的期末复习时间是足够的,不过想学好,就得平时也努力,上课的收获自然是不会小的~所以我这学期开始觉得上课是有意义的~~也因为现在逃课少了,自己的时间也不算太多了~现阶段其实自己也有很多计划的,就是落实下去一般都挺困难的~所以下面随便记录一下今年希望完成的计划:

1.因为自己一直想做一套自己的博客主题,又由于这并不困难,而且自己对方面也算入门了,因此也该搞些自己的东西了,不过现在进度还仅仅停留在PSD设计阶段……所以希望能尽快完成;

2.现在依然在学习JS的相关知识,不过越学发现自己的欠缺也就越多,现在看周爱民的《JAVASCRIPT语言精髓与编程实践》,读起来某些东西还是感觉有些困难,自己现在还有《悟透JavaScript》《JavaScript设计模式》《高性能网站建设指南》等等那么多好书还没有看~同时自己还想学学VI编辑器,这些真是需要耗不少时间啊;

3.现在自己的前端知识也算是刚刚入门,很多东西都掌握的不牢,感觉是都有影像,但是都不够深入,所以自己也要避免浮躁,继续了解,所以《Web标准设计》也想拿来好好看看,巩固巩固那些自己欠缺的。同时由于前端职业的特殊,还需要对后台语言也要有了解,所以自己还准备在学习JS到一定程度的时候开始学习PHP,同时可以通过做自己感兴趣的一些东西来熟习前端和后台的合作,这个计划也是相当的伟大啊!

4.自己在玩VPS的时候,对Linux的有些东东也感觉挺有兴趣的,所以作为爱好,也应该多了解了解相关只是,包括一些命令的使用,还有bash脚本的编写也都是必须的~同时对Web服务器的搭建的知识也是必须得了解的,既然有目标今后从事Web相关行业,所以这些只是也都是必须的!

5.同时,自己也想能够形成一种独特的信息、知识整合方式,之前看过有人的建议是形成自己的wiki,不过现在还没有实践起来,不过整理起来应该也是挺耗费时间和精力的,这个确实比较难呢~其实平时自己看到一些东西,或者写了一些东西,做了一些东西,能够在blog上记录下来也是不错的,不过老是由于懒惰的原因没能完成~这次搞VPS尤为突出,因为要搞一些东西,然后google下来,操作了,但是下次又搞,还是会忘了,没办法,又得搜,真是浪费时间呢~~

差不多就先写到这儿吧,以后有时间要多来更新更新才是~

JavaScript 数组、Object对象for循环效率对比

原来小航子(山山)跟我说过,多用object对象少用数组对象,因为object的效率要高一些,今天刚好在写一个JS的遇到了一个用数组还是用对象的问题,所以就简单写了测试页面。

详见:http://ghsky.com/lab/090521/test_js_for.html

实验内容:测试内容主要是for循环,因为一般数组都是用for循环来遍历数组元素,而object对象则应该用for..in循环来遍历对象元素,所以主要测试思路就是给object和数组填充大量元素,然后分别测试他们遍历、输出的消耗时间。

实验方法:简单说一下实施方法,首先通过一个随机生成字符串的函数(每次生成字符串长度在0-200个字符间),然后分别将生成字符串存到object对象和数组对象中(通常要生成1000个上述字符串),然后用innerHTML方法在页面中输出,计算遍历、输出时间。

说明:考虑用innerHTML方法输出是因为效率比DOM方法高很多,而且这种效率提高有助于高效检测,其次迭代输出的时候用了 innerHTML += 的方法,虽然这样效率很低,应该考虑用存到一个数组然后在.join('')生成字符串输出,但是考虑到将object转存数组也有大量时间消耗,所以索性就选择 innerHTML += 的方法输出。

警告:由于此测试页面计算量很大,容易造成浏览器占用较高CPU,同时浏览器假死现象也可能出现,因此在进行测试的时候请确保浏览器没有打开未保存页面或没有进行其他有可能造成损失的操作!

结论:1.经过几次简单的测试,发现通常情况下数组for循环效率要高于object for-in循环,且有时效率甚至高于50%以上,但是测试也发现,相反的结果页可能出现几次,但总体来看数组循环的效率是要高于object对象的for-in循环;
2.同时经过不同浏览器的测试,发现对于各浏览器的JavaScript引擎来说,Chrome 2的V8引擎最优秀,平均耗时很低,且假死现象轻微;其次是Opera,9.6它的速度和Chrome相对,稍慢一些,不过稳定性不如Chrome,过程中会出现“未响应”情况;第三应该是Safari 4 Beta,运算速度稍慢于Opera,但是较为稳定;第四应该归属IE8,运算速度慢于以上各浏览器,不过没有假死现象;最后是Firefox 3.0.10,速度最慢,通常比IE8还慢很多,有时比IE8慢达200%!!看来Firefox 3.0的JavaScript引擎仍需提高啊~

最后此种测试方法可能存在缺陷,欢迎各位DX拍砖,同时也欢迎各位博友在留言中回复两项测试的时间,谢谢~

Page 2 Of 2412345678...Last »