简单说说
最近这几天学习到了平台期了,就是一直处于一个相同的学习水平,怎么也进步不了。之前看jQuery学习了一些常用的方法,操作dom元素、事件、动画效果、ajax等,总感觉自己只是了解了表面,想深入呢,也不知道怎么去深入。哎,又有点小无措的感觉了。
然后呢,七月过去了一半,es678也过了一遍,了解了js新增的语法以及异步编程。对于异步编程现在掌握不好,因为真的真的真的不会后端,什么抓取数据、异步交互都不知道怎么操作的。仔细想了想,剩下的半个月俩星期,我要把HTML5深入一下,其中穿插着复习css重难点、js核心内容。一直学习js会有点枯燥的感觉,所以又增加了数据结构与算法的学习,3-4天学习一个呗。反正以后都会用到的,权当放松了。哈哈哈哈哈哈。
数组
数组也是数据结构的一类,js中的数组封装是相当完整的了,好好学习使用就好了。
这里总结一下数组的优缺点。
优点
- 效率高。通过下标索引的对元素进行高效的操作
- 灵活度高。可以在数组任意位置删除、插入元素
缺点
- 性能低。在数组末尾插入和删除元素时,还体现不出来。但是当对数组的第一个元素插入或删除时,这时候就体现了性能低。在插入时,需要把后面的元素一一的向后移动;在删除时,需要把后面的元素一一向前移动一个位置。数组中的元素需要不断的移动,体现性能低。
- 耗时。耗费时间多
这里补充一点其他语言中的数组,与js中的数组还有一点差别。
比如Java中的ArrayList。
ArrayList扩容机制
举个例子,第一次申请一个空间,这个空间最多能放5个元素,当我们需要放第6个元素时,因为第一次申请的空间不够,所以扩容一倍。
- 首先申请一个新的能放10个元素的空间
- 再把原来的数据复制到这个新空间
- 然后再新空间中追加数据
- 当空间再次用完之后,循环第一步操作,申请20个元素的空间。依次类推,每次扩容上一次空间的一倍。
扩容机制这一点体现了数组这种数据结构的耗时。
这些只是我所了解的一些知识,没有深入。
栈
栈的特点:后进先出(LIFO)。
换句话说就是先进去,后出来。栈的过程就是压栈弹栈的过程,相对来说比较简单。
通过在函数调用时会遇到,比如说执行A函数,A压栈;A函数调用B函数,B压栈;B函数内部又调用了C函数,C压栈。这样,C函数先执行完毕返回值,弹出C;接着回到B函数执行,B函数执行完毕返回后,弹出B;到A函数,A函数执行完弹出A。整个过程结束。
上面的过程我们叫做函数调用栈。在js中是非常常见并且常用的。
基于数组封装栈
这里的封装,主要实现了常用的几个方法,进栈、弹栈、查看元素、判断栈是否为空、查看元素个数
方式一:
function Stack() {
// 1.栈中的元素
this.item = [];
// 2.栈的常用操作
// 在原型上编程 共享的方法
// 2.1 进栈
Stack.prototype.push = function (element) {
return this.item.push(element);
}
// 2.2 出栈
Stack.prototype.pop = function () {
// 返回出栈元素
return this.item.pop();
}
// 2.3 查看栈顶元素 -- 数组中的最后一个元素
Stack.prototype.top = function () {
return this.item[this.item.length - 1];
}
// 2.4 判断栈是否为空
Stack.prototype.isEmpty = function () {
return this.item.length == 0;
}
// 2.5 查看栈中的元素
Stack.prototype.showAll = function () {
return this.item.join(" ");
}
// 2.6 查看栈中的元素个数
Stack.prototype.size = function () {
return this.item.length;
}
}
方式二:
class Stack {
static item = [];
// constructor() {
// this.item = [];
// }
push(element) {
return Stack.item.push(element);
}
pop() {
return Stack.item.pop();
}
top() {
return Stack.item[Stack.item.length - 1];
}
isEmpty() {
return Stack.item.length == 0;
}
showAll() {
return Stack.item.join(" ");
}
size() {
return Stack.item.length;
}
}
测试:
let stack = new Stack();
stack.push(6);
stack.push(5);
stack.push(4);
stack.push(3);
console.log(stack.showAll()); // 6 5 4 3
console.log(stack.top()); // 3
stack.pop(); // 3
stack.pop(); // 4
console.log(stack.showAll()); // 6 5
console.log(stack.top()); // 5
console.log(stack.isEmpty()); // false 不空
console.log(stack.size()); // 2
栈类应用 十进制转换二进制
十进制转换二进制数的原理是:倒取余数法。
这里的倒取,我们可以看作是压栈的过程,最后通过弹栈来获取。
例子:
计算 10
10/2 余数:0
5/2 余数:1
4/2 余数:0
2/2 余数:1
0/2 循环结束
每次使用上一次的商继续计算。这个功能,封装一个方法。
// 使用栈实现十进制转换二进制
// 倒取余数法 —— 余数压栈的操作
function decToBin(decNumber) {
// 1. 需要一个栈容器放余数
let stack = new Stack();
// 循环取余数 直到商为0 跳出循环
// 2. 商小于等于0 不能再进行运算
while (decNumber > 0) {
// 2.1 余数压栈
stack.push(decNumber % 2);
// 2.2 使用上一次的商再次取余数 更新参数为上一次数/2的商 向下取整
decNumber = Math.floor(decNumber / 2);
}
// 3. 出栈 只要栈不空就一直弹栈
let binaryString = [];
while (!stack.isEmpty()) {
binaryString.push(stack.pop());
}
return binaryString.join("");
}
console.log(decToBin(10)); // 1010
ok,今天新增额外学习任务完成!
加油加油!!!!