用户名: 密码: 验证码: QQ--程序群:31736530 动画群:38836599
闪无忧
 
首 页 业界新闻 业界杂谈 Flash教程 Flash源码 Flash图书 Flash酷站 Flex & AIR 供求信息
   本栏目通告:   有意向写收费精品教程的朋友,请联系本站合作
当前位置 :首页>flash教程>Flash应用开发>列表

高效的数组重排算法探究

[来源:SimpleLife blog | 作者:小力 | 时间:2008-05-03 | 点击:  | 收藏本文  【 】]
在程序设计中很多时候我们需要对数组重排,所以探求一种高效的重排算法还是很有必要的。
  上午逛论坛时看到一个帖子中的“简洁、高效”的重排算法,如下:

function randomsort() {
return Math.random()>.5 ? -1 : 1;
}
function arrRandomSort(arr){
arr.sort(randomsort);
}

  仅仅4行代码,当时我那个惭愧啊,自己以前怎么没有想到这么简单的方法了?还绕了一个大圈子来写这个重排。激动之后做了个测试:

function randomsort() {
return Math.random()>.5 ? -1 : 1;
}
function arrRandomSort(arr){
arr.sort(randomsort);
}
_array = [];
for (i = 0;i<1000;i++){
_array.push(Math.random());
}
arr = [];
var t1 = getTimer();
arr = arrRandomSort(_array);
var t2=getTimer();
trace(t2-t1);

  使用上面的算法对一个1000个元素的数组进行重排,执行时间是居然是210毫秒,有些恐怖,初步估计是因为sort函数造成的,因此将上面代码里添加了一个计数器来跟踪sort参数中的函数的执行次数。


_global.n = 1;
function randomsort() {
n++;
return 1;
}
function arrRandomSort(arr){
arr.sort(randomsort);
}
_array = [];
for (i = 0;i<1000;i++){
_array.push(Math.random());
}
arr = [];
var t1 = getTimer();
arr = arrRandomSort(_array);
var t2=getTimer();
trace(t2-t1);
trace(n);

  看来效率的消耗果然是因为sort函数,对这1000个元素的数组进行排序,运行了7153毫秒,randomsort函数被执行了499501次,显然,这段看似简洁的代码其实并不实用。而sort函数内部到底是使用什么算法来完成的这个排序了?以至于需要执行这么多次比较函数。简单排序?快速排序?我也不太清楚,有空了再做进深入测试,暂且不在此文讨论范围之内。
  在我搜索Array.sort的内部实现时发现了一个帖子《用array.sort进行随机排序》,原来有关于用sort方法排序已经引起了很大的争议,而此文作者是站在支持sort排序的立场的,通过与别人的代码比较,他最初得出的结论是Array.sort来做数组重排是有利的,而跟帖中又出现了一个更为高效的算法,此算法跟sort方法相比效率要高很多,特推荐出来供大家借鉴。下面是我用此算法和sort算法做的对比,分别对100个元素的数组进行100次重排,比较其总消耗的时间,结果消耗时间分别为70MS和1448MS,其中红色部分为效率更佳算法:

/*算法一 */
Array.prototype.random = function($lim:Number):Array {
var tmp:Array = this.concat();
var len:Number = tmp.length;
//trace(($lim && $lim<(len-1)) ? $lim : (len-1));
for (var i = 0; i<(($lim && $lim<(len-1)) ? $lim : (len-1)); i++) {
//获取最末索引
var n:Number = len-i;
//索引集合中随机一个
var r:Number = random(n);
//将选出来的元素放置到数组后面,以保证不在随机范围之内
var temp = tmp[r];
tmp[r] = tmp[n-1];
tmp[n-1] = temp;
}
return tmp.slice(-$lim);
};

/*算法二*/
function getRandom() {
return Math.random()<0.5 ? 1 : -1;
}
function arrayRandom(arr) {
arr.sort(getRandom);
return arr;
}
//---------------------------------------------------
//测试次数
var _times = 100;
//生成测试数据
var _array = [];
for (var i = 0; i<100; i++) {
_array.push(i);
}
//算法一:
var t1 = getTimer();
for (i=0; i<_times; i++) {
var arr = new Array();
arr = _array.random();
}
//trace(arr);
var t2 = getTimer();
trace("算法一耗时:"+(t2-t1)+"MS");
//算法二:
var t1 = getTimer();
for (i=0; i<_times; i++) {
var arr = new Array();
arr = arrayRandom(_array);
}
//trace(arr);
var t2 = getTimer();
trace("算法二耗时:"+(t2-t1)+"MS");

  实现原理并不复杂,首先将要重排的数组复制一份来操作,虽然效率上有点消耗但还是值得的,这样保证了原数组的不变动。然后很巧妙地将数组“分为”两个部分,每次从数组左边部分随机取出一个元素,然后将该元素交换到右部分的首元素,而分界线从数组末端往顶端移动,这样就保证了选出来的元素不会再被选出来,对于有N个元素的数组只需要进行N次此类操作就可以实现了数组的重排。
  欢迎大家加入讨论。

//Result
//算法一耗时:70MS
//算法二耗时:1448MS

 

文章如果有错误或者缺少文件,请发邮件提交给我们
上一篇:flash抽奖机制作教程
下一篇:flash模拟逆向最长法中文分词
Tags:     Array 算法 重排 sort
>>> 最新评论:(共有 0 位网友发表了评论)      查看所有评论
  发表评论
用户名: 新注册) 密码: 匿名评论
评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
·本站发布内容均为客观表达作者观点,不代表闪无忧立场,请勿攻击和漫骂
·用户发表意见仅代表其个人意见,并且承担一切因发表内容引起的纠纷和责任
·本站管理人员有权在不通知用户的情况下删除不符合规定的评论信息或留做证据
·请客观的评价您所看到的资讯,提倡就事论事,杜绝漫骂和人身攻击等不文明行为
  教程分类
  基础操作   动画特效
  应用开发   组件学习
  As程序   动画教程
  Flash cs3   AS 3.0
  FCS/FMS教程   Loading教程
  Flash与Web   Flash教程连载
  相关文章
·FLASH加载XML:可分页相册的制作
·as2进行单个图片角色动作化处理
·Flash Plaery10 Astro 滤镜初体
·Flash Player 10 Astro API新增
·Flash Player 10 Drawing API
·Flash导出SWC&Flex使用SWC
·FLASH推箱子游戏分析(三)推动
·flash打造抽奖类小游戏(不可重
·Flash拖拽问题通用解决代码(含as
·flash SWFUpload debug之旅
  热门文章
·Flash进度条的制作详细讲解(组图)
·flash幻灯片网页效果
·Flash打造简单的飘雪动画视觉特效
·Flash旋转拖尾文字效果的制作教程
·flash水影效果字
·全Flash动画网站实现的基础教学
·超酷flash光晕移动效果
·flash春雷闪电效果
·Flex 3 AdvancedDataGrid的使用(第二
·Flash制作大雪纷飞效果动画
·即拷即用的loading代码
关于我们 - 免责声明 - 网站地图 - 商务服务 - 联系我们 - RSS地图
©CopyRight 2006-2008, 5UFlash.COM, Inc. All Rights Reserved
鲁ICP备06034971号