js:堆栈和队列

JavaScript数组的栈和队列的操作方法。

堆栈和队列

要了解JavaScript数组的堆栈和队列方法的操作,需要先对堆栈和队列基础知识有所了解。在继续后面的内容之前,我们先简单的了解一下堆栈和队列的概念。

栈和队列都是动态的集合,在栈中,可以去掉的元素是最近插入的那一个。栈实现了后进先出。在队列中,可以去掉的元素总是在集合中存在的时间最长的那一个。队列实现了先进先出的策略。

堆栈的基本概念

先上张图:

堆栈的基本概念

栈是一种LIFO(Last-In-First-Out,后进先出)的数据结构,也就是最新添加的项最早被移除。而栈中项的插入(叫做推入)和移除(叫做弹出),只发生在一个位置——栈的顶部。

最开始栈中不含有任何数据,叫做空栈,此时栈顶就是栈底。然后数据从栈顶进入,栈顶栈底分离,整个栈的当前容量变大。数据出栈时从栈顶弹出,栈顶下移,整个栈的当前容量变小。

比如说,我们在一个箱子中放了很多本书,如果你要拿出第二书,那么你要先把第一本书拿出来,才能拿第二本书出来;拿出第二本书之后,再把第一本书放进去。

ECMAScript为数组专门提供了 push()pop() 方法,以便实现类似栈的行为。 push() 方法可以接收任意数量的参数,把它们逐个添加到数组末尾,并返回修改后数组的长度。而 pop() 方法则从数组末尾移除最后一项,减少数组的length值,然后返回移除的项。

队列的基本概念

栈数据结构的访问规则是LIFO(后进先出),而队列数据结构的访问规则是FIFO(Fist-In-First-Out,先进先出)。队列在列表的末端添加项,从列表的前端移除项。如下图所示:

队列的基本概念

比如说火车站排队买票,先到的先买,买好的先走。

入队列操作其实就是在队尾追加一个元素,不需要任何移动,时间复杂度为O(1)。出队列则不同,因为我们已经架设下标为0的位置是队列的队头,因此每次出队列操作所有元素都要向前移动。如下图所示:

队列的基本概念

ECMAScript为数组专门提供了 shift()unshift() 方法,以便实现类似队列的行为。由于 push() 是向数组末端添加数组项的方法,因此要模拟队列只需一个从数组前端取得数组项的方法。实现这一操作的数组方法就是 shift() ,它能够移除数组中的第一个项并返回该项,同时将数组长度减1

顾名思义, unshift()shift() 的用途相反:它能在数组前端添加任意个数组项并返回新数组的长度。因此,同时使用 unshift()pop() 方法,可以从相反的方向来模拟队列,即在数组的前端添加数组项,从数组末端移除数组项。

push()方法

该方法是向数组末尾添加一个或者多个元素,并返回新的长度。

push()方法可以接收任意数量的参数,把它们逐个添加到数组的末尾,并返回修改后数组的长度。如:

var arr = []; //创建一个空数组
console.log(arr); // []
console.log("入栈"); // 入栈
arr.push(1); // 将1添加到数组arr中
console.log(arr); // [1]
arr.push(2); //将2添加到数组arr中
console.log(arr); //[1,2]
arr.push([3,4]); // 将数组[3,4]添加到arr中
console.log(arr); // [1,2,[3,4]]
console.log(arr.length); // 3

在Chrome浏览器控制台输出的效果如下图所示:

push方法

pop()方法

pop()方法刚好和push()方法相反。pop()方法删除数组的最后一个元素,把数组的长度减1,并且返回它被删除元素的值,如果数组变为空,则该方法不改变数组,返回undefine值。如下代码演示:

var arr = [1,2,3,4]; //创建一个数组
console.log(arr); // [1,2,3,4]
console.log(arr.length); // 4
console.log("出栈,后进先出"); // 出栈,后进先出
arr.pop();
console.log(arr); //  // [1,2,3]
arr.pop();
console.log(arr); // [1,2]
arr.pop();
console.log(arr); // [1]
arr.pop();
console.log(arr); // []

在Chrome浏览器控制台输出的效果如下图所示:

pop方法

unshift()方法

unshift()方法是向数组的开头添加一个或多个元素,并且返回新的长度。

var arr = []; //创建一个空的数组
console.log(arr); // []
console.log("入队"); // 入队
arr.unshift(1,2,3,4); // 将1,2,3,4推入到数组arr
console.log(arr); // [1,2,3,4]
console.log(arr.length); // 4

在Chrome浏览器控制台输出的效果如下图所示:

unshift方法

shift()方法

shift()方法和unshift()方法恰恰相反。该方法用于把数组的第一个元素从其中删除,并返回被删除的值。如果数组是空的,shift()方法将不进行任何操作,返回undefined的值。

var arr = [1,2,3,4]; // 创建一个数组
console.log(arr); // [1,2,3,4]
arr.shift(); // 取得第一项
console.log(arr); // [2,3,4]
arr.shift(); // 取得第一项
console.log(arr); // [3,4]
arr.shift(); // 取得第一项
console.log(arr); // [4]
arr.shift(); // 取得第一项
console.log(arr); // []

在Chrome浏览器控制台输出的效果如下图所示:

shift方法

简单得回忆一下:

  • push()方法可以在数组的末属添加一个或多个元素
  • shift()方法把数组中的第一个元素删除
  • unshift()方法可以在数组的前端添加一个或多个元素
  • pop()方法把数组中的最后一个元素删除

JavaScript实现类似栈和队列的行为

了解这几种方法之后,我们就可以将它们结合起来,轻松的实现类似栈和队列的行为。

实现类似栈的行为

push()pop()结合在一起,我们就可以实现类似栈的行为:

//创建一个数组来模拟堆栈
var a=new Array();
console.log(a);
//push: 在数组的末尾添加一个或更多元素,并返回新的长度
console.log("入栈");
a.push(1)
console.log(a);//----->1
a.push(2);
console.log(a);//----->1,2
a.push(3);
console.log(a);//----->1,2,3
a.push(4);
console.log(a);//----->1,2,3,4
console.log("出栈,后进先出");
console.log(a);
//pop:从数组中把最后一个元素删除,并返回这个元素的值
a.pop();//----->4
console.log(a);
a.pop();//----->3
console.log(a);
a.pop();//----->2
console.log(a);
a.pop();//----->1
console.log(a);

在Chrome浏览器控制台输出的效果如下图所示:

JavaScript实现类似栈的行为

实现类似队列的行为

shift()push()方法结合在一起,可以像使用队列一样使用数组。即在数组的后端添加项,从数组的前端移除项:

//创建一个数组来模拟队列
var a=new Array();
console.log(a);
//push: 在数组的末尾添加一个或更多元素,并返回新的长度
console.log("入队");
a.push(1)
console.log(a);//----->1
a.push(2);
console.log(a);//----->1,2
a.push(3);
console.log(a);//----->1,2,3
a.push(4);
console.log(a);//----->1,2,3,4
console.log("出队,先进先出");
console.log(a);
//shift:从数组中把第一个元素删除,并返回这个元素的值
a.shift();//----->1
console.log(a);
a.shift();//----->2
console.log(a);
a.shift();//----->3
console.log(a);
a.shift();//----->4
console.log(a);

在Chrome浏览器控制台输出的效果如下图所示:

JavaScript实现类似队列的行为

除此之外,还可以同时使用unshift()pop()方法,从相反的方向来模拟队列,即在数组的前端添加项,从数组的后端移除项。如下面的示例所示:

//创建一个数组来模拟队列
var a=new Array();
console.log(a);
//unshift: 在数组的前端添加一个或更多元素,并返回新的长度
console.log("入队");
a.unshift(1)
console.log(a);//----->1
a.unshift(2);
console.log(a);//----->2,1
a.unshift(3);
console.log(a);//----->3,2,1
a.unshift(4);
console.log(a);//----->4,3,2,1
console.log("出队,先进先出");
console.log(a);
//pop:从数组中把最一个元素删除,并返回这个元素的值
a.pop();//----->4
console.log(a);
a.pop();//----->3
console.log(a);
a.pop();//----->2
console.log(a);
a.pop();//----->1
console.log(a);

在Chrome浏览器控制台输出的效果如下图所示:

JavaScript实现类似队列的行为

push()方法和unshift()方法的性能测试

以下这部分内容来自于《JavaScript学习:JavaScript的数组实现队列与堆栈的方法》一文。

Array的push()unshift()方法都能给当前数组添加元素,不同的是,push()是在末尾添加,而unshift()则是在开头添加,从原理就可以知道,unshift()的效率是较低的。原因是,它每添加一个元素,都要把现有元素往下移一个位置。但到底效率差异有多大呢?下面来简单测试一下。

/*
关于代码中"var s=+newDate();"的技巧说明
解释如下:=+这个运算符是不存在的;
+相当于.valueOf();
+new Date()相当于new Date().valueOf()
//4个结果一样返回当前时间的毫秒数alert(+new Date());alert(+new Date);var s=new Date();alert(s.valueOf());alert(s.getTime());
*/
var arr = [ ];
var startTime = +new Date(); //+new Date()相当于new Date().valueOf(),返回当前时间的毫秒数
// push性能测试 
for (var i = 0; i < 100000; i++) { arr.push(i); 
}
var endTime = +new Date();
console.log("调用push方法往数组中添加100000个元素耗时"+(endTime-startTime)+"毫秒"); startTime = +new Date(); 
arr = [ ]; 
// unshift性能测试 
for (var i = 0; i < 100000; i++) { arr.unshift(i); 
}
endTime = +new Date();
console.log("调用unshift方法往数组中添加100000个元素耗时"+(endTime-startTime)+"毫秒"); 

这段代码分别执行了100000push()unshift()操作,在chrome浏览器运行一次,得到的结果如下图所示:

性能测试

可见,unshift()push()要慢差不多100倍!因此,平时还是要慎用unshift(),特别是对大数组。那如果一定要达到unshift()的效果,可以借助于Array的reverse()方法,Array的reverse()的方法能够把一个数组反转。先把要放进数组的元素用push()添加,再执行一次reverse(),就达到了unshift()的效果。比如:

//创建一个数组来模拟堆栈
var a=new Array();
//使用push方法在数组的末尾添加元素
a.push(1)
a.push(2);
a.push(3);
a.push(4);
console.log("数组反转之前数组中的元素顺序");
console.log(a);//----->1,2,3,4
//Array有一个叫做reverse的方法,能够把一个数组反转。先把要放进数组的元素用push添加,再执行一次reverse,就达到了unshift的效果
a.reverse();//使用reverse方法将数组进行反转
console.log("数组反转之后数组中的元素顺序");
console.log(a);

在chrome浏览器控制台输出的效果如下图所示:

性能测试

从运行结果来看,数组元素的顺序已经反转过来了。

reverse()方法的性能测试

var arr = [ ], s = +new Date; 
for (var i = 0; i < 100000; i++) { arr.push(i); 
}
//调用reverse方法将数组里面的100000元素的顺序反转
arr.reverse(); 
console.log("调用reverse方法将数组里面的100000元素的顺序反转耗时:"+(+new Date - s)+"毫秒");

在chrome浏览器控制台输出的效果如下图所示:

性能测试

从运行效果中可以看到,reverse()方法的性能极高,可以放心使用。

总结

堆栈和队列

本文主要介绍了JavaScript数组的push()pop()shift()unshift()方法。并且如何通过组合这几种方法实现类似栈和队例的行为。

js中删除堆栈:

1:js中的splice方法

  splice(index,len,[item])    注释:该方法会改变原始数组。

splice有3个参数,它也可以用来替换/删除/添加数组内某一个或者几个值

index:数组开始下标        len: 替换/删除的长度       item:替换的值,删除操作的话 item为空

如:arr = ['a','b','c','d']

删除 ----  item不设置

arr.splice(1,1)   //['a','c','d']         删除起始下标为1,长度为1的一个值,len设置的1,如果为0,则数组不变

arr.splice(1,2)  //['a','d']          删除起始下标为1,长度为2的一个值,len设置的2

替换 ---- item为替换的值

arr.splice(1,1,'ttt')        //['a','ttt','c','d']         替换起始下标为1,长度为1的一个值为‘ttt’,len设置的1

arr.splice(1,2,'ttt')        //['a','ttt','d']         替换起始下标为1,长度为2的两个值为‘ttt’,len设置的1

 

添加 ----  len设置为0,item为添加的值

arr.splice(1,0,'ttt')        //['a','ttt','b','c','d']         表示在下标为1处添加一项‘ttt’

看来还是splice最方便啦

2:delete       delete删除掉数组中的元素后,会把该下标出的值置为undefined,数组的长度不会变

如:delete arr[1]  //['a', ,'c','d']     中间出现两个逗号,数组长度不变,有一项为undefined

还有其他几种自定义方法,参考这里

原文: https://www.w3cplus.com/javascript/array-part-3.html © w3cplus.com

转载自:https://www.w3cplus.com/javascript/array-part-3.html

https://www.cnblogs.com/Joans/p/3981122.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/568591.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Python爬虫】微信公众号历史文章和文章评论API分析

上一篇文章爬取微信公众号文章信息准备工作介绍了微信公众号历史文章和文章评论API的组成情况&#xff0c;历史文章API格式&#xff1a;https://mp.weixin.qq.com/mp/profile_ext?actiongetmsg&__bizMjM5NjAxOTU4MA&fjson&offset10&count10&is_ok1&sc…

MySql的Delete、Truncate、Drop分析

MySql的Delete、Truncate、Drop分析 相同点&#xff1a; truncate 和不带 where 子句的 delete&#xff0c;以及 drop 都会删除表内的数据 不同点:  1. truncate 和 delete 只删除数据不删除表的结构(定义)   drop 语句将删除表的结构被依赖的约束(constrain)、触发器(…

【Python】Python简介和Python解释器

计算机语言的种类非常的多&#xff0c;总的来说可以分成机器语言&#xff0c;汇编语言&#xff0c;高级语言三大类。 机器语言(二进制)→汇编语言→&#xff08;前面两种语言是与硬件进行交互&#xff09; →高级语言&#xff08;面向过程语言(C语言)→面向对象语言&#xff09…

python 判断当前时间是否为零点

import time time_now int(time.time()) #unix时间time_local time.localtime(time_now) #转换为win_timedt time.strftime("%H:%M:%S", time_local)# 转换成新的时间格式(18:59:20)adt.split(:)b[]for a in dt.split(:):b.append(a)c.join(b)if c000000:print(是…

多任务场景下单线程异步多线程多进程

多任务的场景&#xff1a;1.爬取不同url的内容&#xff0c;爬取同一个url分页内容。比如&#xff1a;豆瓣图书 Top 250 https://book.douban.com/top250?start0 实现豆瓣图书Top250的抓取工作&#xff0c;并存入excel中&#xff0c;如果采用的串行爬取方式&#xff0c;每次爬完…

django 按天水平分表并插入数据

db pymysql.connect("localhost", "数据库管理员名", "数据库密码", "数据库名")cursor db.cursor()unix_time str(int(time.time()))win_time datetime.datetime.now().strftime(%Y%m%d)table_name engineeringdata win_timesq…

【Python】单线程异步多线程多进程实例

上一篇文章主要介绍了多任务场景下单线程异步、多线程、多进程如何选择&#xff0c;链接&#xff1a;多任务场景下单线程异步多线程多进程 这里主要通过三个实例去验证一下简单的多任务场景下&#xff0c;三种方式的耗时情况&#xff0c;假设有10个互不关联的10个任务 多进程版…

python及pycharm2018软件安装教程

python及pycharm2018软件安装教程 python 3.6.5及pycharm2018.1.1 Win版32/64位下载地址&#xff1a; https://pan.baidu.com/s/1KdECgnrARK4HubPeFSKCTw 密码&#xff1a;bwc5 Python及PyCharm简介&#xff1a; Python 是一种面向对象的解释型计算机程序设计语言。是纯粹的自由…

【Python爬虫】requests与urllib库的区别

我们在使用python爬虫时&#xff0c;需要模拟发起网络请求&#xff0c;主要用到的库有requests库和python内置的urllib库&#xff0c;一般建议使用requests&#xff0c;它是对urllib的再次封装&#xff0c;它们使用的主要区别&#xff1a; requests可以直接构建常用的get和post…

2059 - authentication plugin 'caching_sha2_password' -navicat连接异常问题解决

使用navicat 连接 mysql 8.0.11 报 "2059 - authentication plugin caching_sha2_password ..." 解决办法&#xff1a; 进入mysql命令行然后输入 ALTER USER root% IDENTIFIED WITH mysql_native_password BY root1;

【教育】世界上最伟大的25个教育法则

鱼缸法则 心灵的成长需要自由 一家公司里&#xff0c;职员把几条小鱼放在一个鱼缸里&#xff0c;好几年了&#xff0c;鱼竟然还是那么小&#xff0c;于是大家都认为这鱼就是小个头。一天鱼缸被打破了&#xff0c;就把它们养在院子塘里&#xff0c;没想这些鱼疯了似地长得很大…

mysql安装版安装

1、到mysql官网。选择windows&#xff0c;选择.msi文件。下载 2、双击安装。安装时选择server即可ok。 3、在输入密码时&#xff0c;切记勿用小键盘上的数字&#xff08;可能会造成后期连接数据库密码错误&#xff09; 4、安装完成后&#xff0c;打开sql命令行。输入密码校正…

【测试工具】在linux测试环境安装bug管理工具禅道

在我们测试中&#xff0c;为了方便管理测试流程&#xff0c;提交测试发现的bug&#xff0c;我们需要使用到bug管理工具。有些大公司可能会自己开发一些bug管理工具&#xff0c;但是我们也会用一些开源的bug管理工具&#xff0c;比如Bugzilla&#xff0c;Redmine&#xff0c;Tra…

PyCharm点击设置没反应,无法进行设置

首先检查下是不是装了中文汉化包resources_cn.jar 如果有的话&#xff0c;解决办法&#xff1a;1.更换一个汉化包或者将原来的resources_en.jar也放进lib目录下 2.将汉化包都删除&#xff0c;只留下原版的resources_en.jar 转载自https://blog.csdn.net/xiangshangbashaon…

【测试工具】在linux测试环境访问禅道数据库

上一篇文章我们介绍了如何在linux测试环境安装bug管理工具禅道&#xff0c;现在我们来介绍一下如何访问禅道的数据库&#xff0c;访问数据库有什么用呢&#xff1f;首先&#xff0c;我们可以更改我们安装后的管理系统的名称&#xff08;改为自己公司名称&#xff09;&#xff0…

在命令提示符(cmd)下怎样复制粘贴(详细版)

我们的命令提示符面板&#xff0c;不能选中复制。应该怎么办呢&#xff1f; 按照下面的方法即可解决 输入“cmd”&#xff0c;确认。 此时打开了cmd窗口&#xff0c;在图中位置右键选择“属性”。 4 在弹出的窗口中&#xff0c;勾选“快速编辑模式”。 5 复制方框1中的文字…

【Python】提升Python程序性能的好习惯2

掌握一些技巧&#xff0c;可尽量提高Python程序性能&#xff0c;也可以避免不必要的资源浪费。 追求性能极限是一个有趣的游戏, 而过度优化就会变成嘲弄了。虽然Python授予你与C接口无缝集成的能力, 你必须问自己你花数小时的艰辛优化工作用户是否买帐. 另一方面, 牺牲代码的可…

python各种库安装

1、安装django pip install django 安装成功测试&#xff1a;进入cmd--》输入python--》输入import django-->输入 django.get_version(),若正常显示则说明安装成功 2、更新pip python -m pip install --upgrade pip 3、安装pymysql pip install pymysql 出现错误&…

【工具】SecureCRT安装和注册

SecureCRT是一款支持SSH&#xff08;SSH1和SSH2&#xff09;的终端仿真程序&#xff0c;简单地说是Windows下登录UNIX或Linux服务器主机的软件。 SecureCRT支持SSH&#xff0c;同时支持Telnet和rlogin协议。SecureCRT是一款用于连接运行包括Windows、UNIX和VMS的理想工具。通过…

Windows下如何查看某个端口被谁占用并强制关闭

一、查看那个端口被调用 我告诉大家一个方法&#xff0c;^_^。 1、 开始—->运行—->cmd&#xff0c;或者是windowR组合键&#xff0c;调出命令窗口&#xff1b; 2、输入命令&#xff1a;netstat -ano&#xff0c;列出所有端口的情况。在列表中我们观察被占用的端口&a…