2. 栈
栈 是一个遵从 后进先出 原则的有序集合。
2.1 基于数组的 Stack
class Stack {
constructor(){
this.items = [];
}
push(value){
this.items.push(value);
}
pop(){
let val = this.items[this.items.length - 1];
this.items.pop()
return val;
}
peek(){
return this.items[this.items.length - 1];
}
clear(){
this.items = [];
}
isEmpty(){
return this.items.length === 0;
}
size(){
return this.items.length;
}
}
2.2 基于JS对象的 Stack
this.items = {};
}
push(value){
this.items[this.count] = value;
this.count ++;
}
pop(){
if(this.count === 0){
return undefined;
}
this.count --;
const val = this.items[this.count];
delete this.items[this.count];
return val;
}
peek(){
if(this.count === 0){
return undefined;
}
return this.items[this.count - 1];
}
size(){
return this.count;
}
clear(){
this.items = {};
this.count = 0;
}
isEmpty(){
return this.count === 0;
}
toString(){
if(this.isEmpty()){
return '';
}
let objString = `${this.items[0]}`;
console.log(objString);
for(let i = 1; i < this.count; i ++){
objString = `${objString},${this.items[i]}`
}
return objString;
}
}
2.3 保护数据结构内部元素
let s = new Stack()
s.push(12);
s.push(11);
console.log(s);
console.log(Object.getOwnPropertyNames(s));
console.log(Object.keys(s));
console.log(s.items);
表明 count items 属性是公开的,并没有得到保护。
2.3.1 下划线命名约定
class Stack{
constructor(){
this._count = 0;
this._items = {};
}
}
这种方式只是一种约定,不能保护数据。
2.3.2 用ES6的限定作用域 Symbol 实现
const _items = Symbol('stackItems');
class Stack{
constructor(){
this[_items] = [];
}
push(value){
this[_items].push(value);
}
}
console.log(_items);
console.log(typeof _items);
const s = new Stack()
s.push(12);
s.push(223);
console.log(s);
let sy = Object.getOwnPropertySymbols(s);
console.log(sy);
console.log(sy[0]);
s[sy[0]].push(88);
console.log(s);
这种方法是一个假的私有属性。
因为Object.getOwnPropertySymbols() 该方法可以取得类里面声明的所有 Symbols 属性。
2.3.3 用ES6的WeakMap 实现类
WeakMap 可以存储键值对。- 实现了真正的属性私有,但是代码可读性不强。
const items = new WeakMap();
class Stack{
constructor(){
items.set(this, []);
}
push(value){
const s = items.get(this);
s.push(value);
}
pop(){
const s = items.get(this);
return s.pop();
}
}
2.4 进制转换
2.4.1 十进制转二进制
function decimalToBinary(value){
const restStack = new Stack();
console.log(restStack);
let number = value;
let rem = 0;
let binaryString = ''
while(number > 0){
rem = Math.floor(number % 2);
number = Math.floor(number / 2);
restStack.push(rem);
}
while(!restStack.isEmpty()){
binaryString += restStack.pop()
}
return binaryString;
}
console.log(decimalToBinary(10));
2.4.2 进制转换算法
function baseConver(decValue, base){
const restStack = new Stack();
const digitis = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
let number = decValue;
let rem = 0;
let baseString = ''
if(!(base >= 2 && base <= 36)){
return '';
}
while(number > 0){
rem = Math.floor(number % base);
number = Math.floor(number / base);
restStack.push(rem);
}
while(!restStack.isEmpty()){
baseString += digitis[restStack.pop()];
}
return baseString;
}
console.log(baseConver(100345, 35));
console.log(baseConver(16, 4));
|