本博客学习书籍:《学习JavaScript数据结构与算法》
本博客学习章节:第三章、第四章、第五章
栈
栈是一种遵循后进先出(LIFO last in first out)原则的有序集合。新添加的或待删除的元素都保存在栈的同一端,称作栈顶,另一端就叫栈底。
比如考试时发考卷,一摞考卷都是从最上面开始发给考生,如果考生没到场也是把该考生的卷子放上面而不是塞最底下。
把js数组看做一个长方体,每个格子里都有数组元素。但是,我们只能对数组的尾部进行元素的添加push()
和删除pop()
。把这个数组长方体立起来,原来的数组尾部
就是我们所说的栈顶
啦
创建栈
// es6语法
class Stack {
constructor(items) {
this.items = items || [];
}
push(value){
this.items.push(value);
}
// ...
}
let s1 = new Stack();
s1.push(1222);
s1.print();
我们是把Stack
作为栈
来操作的,但此时数组items
却是公共变量,容易被用数组方法从中间移除或添加元素,所以需要将数组items声明为私有变量
。用WeakMap
可以将变量声明为私有变量。
let Stack = (function(){
const items = new WeakMap();
class Stack {
constructor(arr) {
items.set(this, arr || []);
}
push(value){
// 栈顶添加元素
items.get(this).push(value);
}
pop(){
// 栈顶移除元素
return items.get(this).pop();
}
peek(){
// 获取栈顶元素
let _arr = items.get(this);
return _arr[_arr.length - 1];
}
isEmpty(){
return items.get(this).length == 0;
}
size(){
return items.get(this).length;
}
clear(){
items.set(this, []);
}
print(){
return items.get(this);
}
}
return Stack;
})();
用栈数据结构实现十进制转换
- 十进制转二进制:将十进制num和2整除,得到的商继续和2整除,直到结果商是0为止。这过程中,按顺序取余数就是num的二进制表示,余数是0或1
- 十进制转八进制:将十进制num和8整除,得到的商继续和8整除,直到结果商是0为止。这过程中,按顺序取余数就是num的八进制表示,余数是0到7
- 十进制转十六进制:将十进制num和16整除,得到的商继续和16整除,直到结果商是0为止。这过程中,按顺序取余数就是num的八进制表示,余数是0到9,加上A,B,C,D,E,F(对应10,11,12,13,14,15)
function decimalToOther(number, base){
let remStack = new Stack();
let rem, baseStr = '', digits = '0123456789ABCDEF';
while(number > 0){
rem = Math.floor(number % base);
remStack.push(rem); // 余数进栈
number = Math.floor(number / base);
}
while(!remStack.isEmpty()){
// 取到余数对应的字符,如0-'0', 1-'1', 2-'2', 10-'A'
baseStr += digits[remStack.pop()];
}
return baseStr;
}
// 10的二进制
decimalToOther(10, 2)
// 10的8进制
decimalToOther(10, 8)
// 10的16进制
decimalToOther(10, 16)
队列
队列是一种遵循先进先出(FIFO first in first out)原则的有序集合。队列在尾部添加新元素,并从顶部删除元素。最新添加的元素必须排在队列的末尾。
比如大夏天排队买冰淇淋,不允许插队。
用数组实现队列,就相当于队首 == 数组头部,队尾 == 数组尾部
。
创建队列
let Queue = (function(){
const items = n