关于实现js冒泡排序可视化的思路分析

<h3>需求分析</h3>
<ul>
<li><b>两个区域:</b>
<ul>
<li>操作区域:可供操作的区域</li>
<li>呈现区域:将数据可视化的区域</li>
</ul>
</li>
<li><b>两个模块</b>(操作区域内):
<ul>
<li>输入模块:可供数据输入的模块</li>
<li>功能模块:可选功能的模块</li>
</ul>
</li>
<li><b>五个功能</b>(功能模块内):
<ul>
<li>数据插入功能</li>
<li>数据删除功能</li>
<li>随机生成数据功能(1~100)</li>
<li>数据排序功能(冒泡排序)</li>
<li>数据打乱排序功能</li>
</ul>
</ul>


<h3>功能实现设想</h3>
<h5>流程图</h5>


流程图
流程图

<h3>具体实现分析</h3>
<strong>基本思路:将数据储存在数组dataList[ ]中,根据需求对数组进行操作,并将操作后的数组渲染在网页上(即数据可视化)</strong>


<h5>实现过程</h5>
<ol>
<li>添加函数
<ul>
<li>渲染函数


渲染函数主要是通过dom操作,将数据添加到文档中。关于数据可视化,我采用的方式是以div作为一个数据bar,根据数据的大小不同,动态地给每个div设定高度,并且给每个div添加背景颜色,这样,在网页上看起来,就和柱状图一样了。
<pre><code>
function render(){

var numList = document.getElementById("num-list");

//每次调用渲染函数都将原numList里内容清空并重新渲染

numList.innerHTML = "" ;

for(var m = 0; m < dataList.length; m++){

numList.innerHTML += "<div>" + "</div>" ;

//取得包含数据的div的nodelist

var dataDiv = numList.querySelectorAll("div");

//给每个数据的div设定高度

dataDiv[m].style.height = dataList[m]*5 + "px";

}

}
</code></pre>
</li>


<li>打乱排序函数


因为js的数组十分强大,自带<code>sort()</code>方法,所以我们只需要随机生成-1(正序)或者1(倒序),sort方法会自动帮我们对数组进行处理。
<pre><code>function randomSort(){

return Math.random()>0.5?-1:1;

}
</code></pre>
</li>
<li>随机生成函数


与打乱排序函数相同,这个函数里同样使用了<code>Math.random()</code>方法,这个方法随机生成[0,1)范围内的数字,只要稍作变化,便能得到想要的[1,100]内的随机数。
<pre><code>
function randomGeneration(){

for(var x=0; x<19; x++){
dataList[x] = parseInt(Math.random()*100+1);
}
}
</code></pre>
</li>
<li>冒泡排序函数
<pre><code>
function sortNum(arr){

for (var i = arr.length-1; i > 0; i--) {

for(var j = 0; j < i; j++){

if (arr[j] > arr[j+1]) {

var temp = arr[j];

arr[j] = arr[j+1];

arr[j+1] = temp;

//将每一次交换的数组存到state中,state是数组的数组

state.push(JSON.parse(JSON.stringify(arr)));

}

}

}

}
</code></pre>
关于这个排序函数,其实没有太多需要描述的地方,就是一个很简单的冒泡排序。值得一提的是,后面的state是一个数组,通过JSON数据格式,将每一次移动后原来数据的状态储存到了state中,在后面我们会根据这个state进行操作,以实现数据bar随着排序过程移动的视觉效果。
</li>
</ul>
</li>


<li>给各个按钮绑定事件


设定一个初始函数<code>init()</code>,在<code>init()</code>中给各个按钮绑定事件,然后在最后调用<code>init()</code>函数即可。


<pre><code>
btn.onclick = function(){

//添加事件

}
</code></pre>


具体来说,一共有七个按钮,来实现五个功能,他们分别是:<b>向左插入数据、向右插入数据、从左边删除数据、从右边删除数据、冒泡排序、打乱排序、随机生成数据。</b>
<ul>
<li>向左插入数据


先使用dom操作获得用户输入的数据,然后通过数组的<code>unshift()</code>方法,将数据从数组坐标较小的那一方(即前方/左方)插入数组,然后将数组渲染在页面上。
<pre><code>
inleftBtn.onclick = function(){

var data = document.getElementById("num- input").value.trim();

dataList.unshift(data);

render();
}
</code></pre>
向右插入数据的操作同理,区别在于使用的是数组的<code>push()</code>方法。
</li>


<li>从左边删除数据


删除数据的操作与插入数据的操作也很相似,原理也是对数组进行处理之后,进行渲染。
<pre><code>
outLeftBtn.onclick = function(){

var data = document.getElementById("num-input").value.trim();

dataList.shift(data);

render();

}
</code></pre>
<code>shift()</code>方法帮助我们从数组前方(视觉效果为左)删除数组元素。从右边删除数组使用<code>pop()</code>方法。
</li>


<li>冒泡排序
<pre><code>sort.onclick = function(){

sortNum(dataList);

var int = setInterval(forSortRender, 100);

//专门给冒泡排序写一个渲染函数

function forSortRender(){

var s ;

s = state.shift();

var numList = document.getElementById("num-list");

numList.innerHTML = "" ;

if (s !== undefined) {

for(var m = 0; m < s.length; m++){

numList.innerHTML += "<div>" + "</div>" ;

//取得包含数据的div的nodelist

var dataDiv =
numList.querySelectorAll("div");

//给每个数据的div设定样式

dataDiv[m].style.height = s[m]*5 + "px";

}

}

//避免state为空之后,页面也变空

else{

render();

window.clearInterval(int);

}

}

}</code></pre>
之前我们提到,在写冒泡排序函数的时候,创建了一个state数组,用来存储每一趟排序后的数组状态,现在就到了它派上用场的时候。在我们专门为排序过程写的渲染函数中,<code>shift()</code>方法弹出state中第一个数组,即进行了第一次交换后的数组,并返回它,用变量s来保存。此时将s中的数据依次渲染在页面上。<code>setInterval()</code>方法会每隔100ms调用一次这个渲染函数。于是在100ms之后,state又弹出最前面的一个数组,这个数组是原来的dataList[ ]进行了两次交换之后的数组,将它渲染出来,我们在视觉上就形成了数据bar在移动的错觉。


这样,在弹出了交换次数个数组之后,state[ ]变为空,s取不到任何值,就有可能出现排序完成后页面突然变空得情况。于是设置if条件,当s的值为undefined时,使用原来的渲染函数<code>render()</code>渲染排好序的原数组dataList[ ],并且使用<code>clearInterval()</code>停止调用专门给排序写的<code>forSortRender()</code>函数。
</li>
</ul>




</li>

</ol>


<h3>待改进的地方</h3>
<ol>
<li>点击事件实现得很不优雅,每一个按钮都要写一串<code>onclick()</code>,如果使用<code>addEventLister()</code>方法大概会好很多</li>


<li>用一个div盒子实现数据bar似乎有些简单粗暴?暂时没想到更好的方法</li>


<li>渲染函数写了两次,这个有点明显的要功能不要性能的意思,应该可以改进。</li>


<li>在用户输入数据时未作处理,可能收到非法字符。这个是待添加的功能,因为正则表达式没有系统地学习,想找机会认真地学习一遍再来改。</li>


<li>待添加其他几种排序方式,如快排、简单选择排序等,顺便巩固数据结构的知识</li>


<li>待改进样式,待添加颜色选择功能。前端工作者不论何时对于自己手里出来的界面都不能马虎才是!
</li>

</ol>


<h3>总结</h3>


这次demo练习学到了不少js和dom方面的知识,小白表示很满足,但是实现得比较糙,需要改进的地方也很多,学习之路任重道远,加油↖(ω)↗




<h3>demo地址</h3>


https://github.com/escawn/dailyDemo/tree/master/jsVisualSort


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容

  • 工厂模式类似于现实生活中的工厂可以产生大量相似的商品,去做同样的事情,实现同样的效果;这时候需要使用工厂模式。简单...
    舟渔行舟阅读 7,716评论 2 17
  • 某次二面时,面试官问起Js排序问题,吾绞尽脑汁回答了几种,深感算法有很大的问题,所以总计一下! 排序算法说明 (1...
    流浪的先知阅读 1,186评论 0 4
  • 数组排序在日常编程中用到的其实还是比较多的,比如把一组数据按时间排序,按首字母排序,按大小排序等等,那么就让我们一...
    一木_qintb阅读 12,753评论 1 2
  • 数组排序在日常编程中用到的其实还是比较多的,比如把一组数据按时间排序,按首字母排序,按大小排序等等,那么就让我们一...
    xueNoble阅读 2,170评论 0 9
  • Ba la la la ~ 读者朋友们,你们好啊,又到了冷锋时间,话不多说,发车! 1.冒泡排序(Bub...
    王饱饱阅读 1,787评论 0 7