数据结构与算法—栈

栈:是一种遵循先进后出(LIFO Last In First Out)原则的有序集合。新添加或待删除的元素都保存在栈的同一端,称作栈顶,另一端就叫栈底

添加
移除

1.创建一个基于数组的栈

push: 添加一个(或几个)新元素到栈顶
pop:移除栈顶的元素,同时返回被移除的元素
peek:返回栈顶的元素,不对栈做任何修改
isEmpty: 如果栈里没有任何元素就返回true, 否则返回false
size: 返回栈里的元素个数
clear: 移除栈里的所有元素

两种方式:

function Stack() {
    this.items = []
    Stack.prototype.push = (element) => {
        this.items.push(element)
    }
    Stack.prototype.pop = () => {
        return this.items.pop()
    }
    Stack.prototype.peek = () => {
        return this.items[this.items.length - 1]
    }
    Stack.prototype.isEmpty = () => {
        return this.items.length === 0
    }
    Stack.prototype.size = () => {
        return this.items.length
    }
    Stack.prototype.clear = () => {
        this.items = []
    }
}
class Stack {
    constructor() {
        this.items = []
    }
    
    push(element) {
        this.items.push(element)
    }

    pop() {
        return this.items.pop()
    }

    peek() {
        return this.items[this.items.length - 1]
    }

    isEmpty() {
        return this.items.length === 0
    }

    size() {
        return this.items.length
    }

    clear() {
        this.items = []
    }
}

使用 Stack 类

const stack = new Stack()
stack.push(2)
stack.push(4)
stack.isEmpty()
stack.pop()
stack.peek()
stack.size()
stack.clear()

2.创建一个基于 JavaScript 对象的 Stack 类

基于对象与基于数组两种方式创建Stack对比:相对于对象,使用数组时,大部分方法的时间复杂度是O(n),且数组是一个有序集合,为了保证元素排列有序,它会占用更多的内存空间。

class Stack {
    constructor() {
        this.items = {}
        this.count = 0
    }
    push(element) {
        this.items[this.count] = element
        this.count++
    }
    size() {
        return this.count
    }
    isEmpty() {
        return this.count === 0
    }
    pop() {
        if (this.isEmpty()) {
            return undefined
        }
        this.count--
        const result = this.items[this.count]
        delete this.items[this.count]
        return result
    }
    peek() {
        if (this.isEmpty()) {
            return undefined
        }
        return this.items[this.count - 1]
    }
    clear() {
        this.items = {}
        this.count = 0
    }
    // 以字符串形式返回栈的内容
    toString() {
        if (this.isEmpty()) {
            return ''
        }
        let objString = `${this.items[0]}`
        for (let i = 1; i < this.count; i++) {
            objString = `${objString},${this.items[i]}`
        }
        return objString
    }
}
用栈解决问题(实现从十进制转二进制)

十进制转二进制

function decimalToBinary(decNumber) {
    const remStack = new Stack()
    let number = decNumber
    let rem
    let binaryString = ''
    while (number > 0) {
        rem = Math.floor(number % 2)
        remStack.push(rem)
        number = Math.floor(number / 2)
    }
    while (!remStack.isEmpty()) {
        binaryString += remStack.pop().toString()
    }
    return binaryString
}
进制转换算法(将十进制转换成基数为2~36的任意进制)
/**
 * @method
 * @param descNumber {Number}  十进制数字
 * @param base {Number}  十进制数字
 * @returns {String} base进制值
 * @desc 进制转换算法(将十进制转换成基数为2~36的任意进制)
*/
function baseConverter(descNumber, base) {
    const remStack = new Stack()
    const digits = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    let number = descNumber
    let rem
    let baseString = ''
    if (!(base >= 2 && base <= 36)) {
        return ''
    }
    while (number) {
        rem = Math.floor(number % base)
        remStack.push(rem)
        number = Math.floor(number / base)
    }
    while (!remStack.isEmpty()) {
        baseString += digits[remStack.pop()]
    }
    return baseString

补充

new 运算符调用函数的具体过程:
  1. 创建一个空对象,将空对象的_proto_成员指向构造函数的prototype;
  2. 把上面创建的空对象赋值赋值构造函数内部的this,用构造函数内部的方法修改空对象;
  3. 如果构造函数中没有返回其它对象,那么返回this,即创建的这个新对象;否者返回构造函数返回的对象;
function new(fn, ...args) {
	if(typeof fn !== 'function' ) {
		throw 'new function the first param must be a function'
	}

	const obj = Object.create(fn.prototype);
	const result = fn.apply(obj, args);
	
	if(result && (typeof result === 'object' || typeof result === 'function')) {
		return result;
	}
	return obj;
}
Object.create() 的实现

Object.create()会将参数对象作为一个新创建的空对象的原型, 并返回这个空对象。

// 简略版
function create(obj) {
	//	新声明一个函数
	function C(){};
	// 将函数的原型指向 obj
	C.prototype = obj;
	// 返回这个函数的实例化对象
	return new C()
}

// 升级版
object.create = function (proto, propertyObject = undefined) {
	if(typeof proto !== 'object' && typeof proto !== 'function') {
		throw new Error();
	} else if(proto === null) {
		throw new Error();
	}

	function F(){};
	F.prototype = proto;
	const obj = new F();
	
	if(propertyObject !== undefined) {
		// Object.defineProperties(obj, props)
		// 方法直接在一个对象上定义新的属性或修改现有属性,并返回该对象。
		Object.defineProperties(obj, propertyObject)
	}

	return obj;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值