数据结构——栈
栈(stack),后进先出 LIFO(Last in First out)
JS数组操作
首先,先做一个js中数组操作的方法整理
- join():将数组中所有元素都转化为字符串并连接在一起
- reverse():将数组中的元素颠倒顺序
- concat():数组拼接的功能 ,返回新数组,原数组不受影响
var colors = ["red","green","blue"];
var colors2 = colors.concat("yellow",["black","brown"]);
//结果:
//colors为数组[“red”,”green”,”blue”];
//colors2为数组[“red”,”green”,”blue”,”yellow”,”black”,”brown”];
-
slice():
截取数组生成新数组,原数组不受影响。
返回的数组包含第一个参数指定的位置和所有到但不含第二个参数指定位置之间的所有元素。
如果为负数,表示相对于数组中最后一个元素的位置。如果只有一个参数,表示到数组末尾。
var aa = [1,2,3,4,5,6]; console.log(aa.slice(2)); //[3,4,5,6] console.log(aa.slice(2,8)); //[3,4,5,6] 超过最大长度,只显示到最后结果 console.log(aa.slice(2,5)); //[3,4,5] console.log(aa.slice(2,-1)); //[3,4,5] 相对于倒数第一个之前 console.log(aa.slice(2,-2)); //[3,4] 相对于倒数第二个之前 console.log(aa.slice(3)); //[4,5,6] 一个参数从第三个到最后 console.log(aa.slice(-2));//[5,6] 一个参数负值从倒数第二个到最后
-
splice():
功能:从数组中删除元素、插入元素到数组中或者同时完成这两种操作。
输入:第一个参数为指定插入或删除的起始位置,第二个参数为要删除的个数。之后的参数表示 需要插入到数组中的元素 。如果只有一个参数,默认删除参数后边的所有元素。
输出:返回一个由删除元素组成的数组。
注意:新建了一个数组,并修改了原数组var aa = [1,2,3,4,5,6]; console.log(aa.splice(4)); //[5,6] 返回删除后的数组 aa; // [1,2,3,4] console.log(aa.splice(2,2)); //[3,4] 从第二位起删除两个元素 aa; //[1,2] console.log(aa.splice(1,0,7,8)); //[]从第一位起删除0个元素,添加7,8到原数组 aa;//[1,7,8,2]
-
push():在数组末尾添加一个或多个元素,并返回新数组长度
-
pop():从数组末尾删除1个元素(删且只删除1个), 并返回 被删除的元素
-
shift():用于把数组的第一个元素从其中删除,并返回第一个元素的值;
-
unshift():可向数组的开头添加一个或更多元素,并返回新的长度。
-
toString():将数组的每个元素转化为字符串
-
indexOf():
要查找的项和(可选的)表示查找起点位置的索引。其中, 从数组的开头(位置 0)开始向后查找。没找到返回-1. 返回查找项的索引值.
比如在"Welcome to Dalian"里找"Dalian"
A. sort()
默认情况下sort()方法没有传比较函数的话,默认按字母升序,如果不是元素不是字符串的话,会调用toString()方法将元素转化为字符串的Unicode(万国码)位点,然后再比较字符。所以用默认方法排序数据是有问题的。
var arr = [20,10,2,1,3];
arr.sort();// [1, 10, 2, 20, 3]
arr.sort(function(a,b){
return a-b; //升序
}); //[1, 2, 3, 10, 20]
arr.sort(function(a,b){
return b-a; //降序
}); //[20,10,3,2,1]
B. forEach():
从头至尾遍历数组,为每个元素调用forEach括号里的函数
输入为一个待遍历函数,函数的参数依次为:数组元素、元素的索引、数组本身
没有返回值,即返回值为undefined
var arr = [1,2,3,4];
arr.forEach(function(value){
alert(value)
});
// 等价于:
var arr = [1, 2, 3, 4];
for (var k = 0, length = arr.length; k < length; k++) {
alert(array[k]);
}
C. map()
调用的数组的每一个元素传递给指定的函数,并返回一个新数组 ,不修改原数组。
var arr = [2,3,4,5,6];
var bb= arr.map(function(x){
return x*x;
});
console.log(bb); // [4, 9, 16, 25, 36]
forEach和map区别:
**forEach适合于你并不打算改变数据的时候,而只是想用数据做一些事情 – 比如存入数据库或则打印出来。**没有返回值,理论上这个方法是没有返回值的,仅仅是遍历数组中的每一项,不对原来数组进行修改;但是可以自己通过数组的索引来修改原来的数组
var res = ary.forEach(function (item,index,input) {
input[index] = item*10;
})
**map()适用于你要改变数据值的时候。**有返回值,map的回调函数中支持return
返回值;return
的是啥,相当于把数组中的这一项变为啥(并不影响原来的数组,只是相当于把原数组克隆一份,把克隆的这一份的数组中的对应项改变了)
var ary = [12,23,24,42,1];
var res = ary.map(function (item,index,input) {
return item*10;
})
console.log(res);//-->[120,230,240,420,10]; 原数组拷贝了一份,并进行了修改
console.log(ary);//-->[12,23,24,42,1]; 原数组并未发生变化
D.filter()
过滤功能,数组中的每一项运行给定函数,返回满足过滤条件组成的数组。形成新数组。
let nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let res = nums.filter((num) => {
return num > 5;
});
console.log(res); // [6, 7, 8, 9, 10]
E.every() 和 some()
F.reduce() 和 reduceRight()
面试题目讲解
首先 应该把题目弄懂
第一次看到题目 我错误的理解为654321依次全部进栈,然后再依次出栈,那么只有一种出栈序列123456,这样显然是理解错误了
那么正确的理解为:按照654321的顺序来进栈,出栈的话随时可出
比如A选项 65先进栈 5出栈 4进栈出栈 3进栈出栈 21进栈 12出栈
栈Stack的封装和测试
栈常见的操作
push()
添加一个新元素到栈顶位置。pop()
移除栈顶的元素,同时返回被移除的元素。peek()
返回栈顶的元素,不对栈做任何修改(该方法不会移除栈顶的元素,仅仅返回它)。isEmpty()
如果栈里没有任何元素就返回true
,否则返回false
。size()
返回栈里的元素个数。这个方法和数组的length
属性类似。toString()
将栈结构的内容以字符串的形式返回。
JavaScript代码实现栈结构
封装
// 栈结构的封装
class Map {
constructor() {
this.items = [];
}
// push(item) 压栈操作,往栈里面添加元素
push(item) {
this.items.push(item);
}
// pop() 出栈操作,从栈中取出元素,并返回取出的那个元素
pop() {
return this.items.pop();
}
// peek() 查看栈顶元素
peek() {
return this.items[this.items.length - 1];
}
// isEmpty() 判断栈是否为空
isEmpty() {
return this.items.length === 0;
}
// size() 获取栈中元素个数
size() {
return this.items.length;
}
// toString() 返回以字符串形式的栈内元素数据
toString() {
let result = "";
for (let item of this.items) {
result += item + " ";
}
return result;
}
}
测试
// push() 测试
stack.push(1);
stack.push(2);
stack.push(3);
console.log(stack.items); //--> [1, 2, 3]
// pop() 测试
console.log(stack.pop()); //--> 3
// peek() 测试
console.log(stack.peek()); //--> 2
// isEmpty() 测试
console.log(stack.isEmpty()); //--> false
// size() 测试
console.log(stack.size()); //--> 2
// toString() 测试
console.log(stack.toString()); //--> 1 2// push() 测试
stack.push(1);
stack.push(2);
stack.push(3);
console.log(stack.items); //--> [1, 2, 3]
// pop() 测试
console.log(stack.pop()); //--> 3
// peek() 测试
console.log(stack.peek()); //--> 2
// isEmpty() 测试
console.log(stack.isEmpty()); //--> false
// size() 测试
console.log(stack.size()); //--> 2
// toString() 测试
console.log(stack.toString()); //--> 1 2
栈结构的简单应用
利用栈结构的特点封装实现十进制转换为二进制的方法。
代码实现
function dec2bin(dec) {
// new 一个 Map,保存余数
const stack = new Map();
// 当不确定循环次数时,使用 while 循环
while (dec > 0) {
// 除二取余法
stack.push(dec % 2); // 获取余数,放入栈中
dec = Math.floor(dec / 2); // 除数除以二,向下取整
}
let binaryString = "";
// 不断地从栈中取出元素(0 或 1),并拼接到一起。
while (!stack.isEmpty()) {
binaryString += stack.pop();
}
return binaryString;
}
测试
// dec2bin() 测试
console.log(dec2bin(100)); //--> 1100100
console.log(dec2bin(88)); //--> 1011000