一起学习数据结构与算法:栈

194 阅读1分钟

// 栈
function Stack(...data) {
	Object.defineProperties(this, {
		// 数据
		data: {
			configurable: false,
			enumerable: true,
			writable: true,
			value: data
		},
		// 长度
		length: {
			configurable: false,
			enumerable: true,
			get() {
				return this.data && this.data.length || 0
			},
			set() {
				return console.warn(`property length is readonly`);
			}
		},
		// 栈顶
		top: {
			configurable: false,
			enumerable: true,
			get() {
				return this.length
			},
			set() {
				return console.warn(`property top is readonly`);
			}
		},
		// 栈底
		bottom: {
			configurable: false,
			enumerable: true,
			get() {
				return 0
			},
			set() {
				return console.warn(`property bottom is readonly`);
			}
		},
	})
}
// 入栈 returns <Array> this.data
Stack.prototype.push = function (...data) {
	while(data.length) {
		this.data.push(data.shift())
	}
	return this.data
}
// 出栈 returns 出栈的元素                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
Stack.prototype.pop = function () {
	return Array.prototype.pop.apply(this.data)
}
// 获取栈顶元素 returns 栈顶元素
Stack.prototype.peak = function () {
	return this.data[this.top - 1]
}
// 获取栈顶元素 returns 栈顶元素
Stack.prototype.foot = function () {
	return this.data[this.bottom]
}
// 清空栈 returns <Array> []
Stack.prototype.clear = function () {
	this.data = []
	return []
}
// 是否为空栈,returns <boolean> [true | false]
Stack.prototype.isEmpty = function () {
	return !this.length
}

const stack = new Stack(1, 2, 3, 4)
console.log(stack.data, stack.length, stack.top, stack.isEmpty())
console.log(stack.push(5, 6, 7))
stack.top = 2
stack.bottom = 0
stack.length = 3
console.log(stack.pop(), stack.data, stack.length, stack.top, stack.isEmpty())
console.log(stack.peak(), stack.data, stack.length, stack.top, stack.isEmpty())
console.log(stack.foot(), stack.data, stack.length, stack.top, stack.isEmpty())
console.log(stack.clear(), stack.data, stack.length, stack.top, stack.isEmpty())


使用两个栈实现队列

console.log(`--------------- Queen 两个栈实现队列 -----------------`)
// stack1原始栈,stack2为stack1的出栈顺序构成的栈
function Queen(...data) {
	this.stack1 = new Stack(...data)
	this.stack2 = new Stack()
}
Queen.prototype.push = function (...data) {
	return this.stack1.push(...data)
}
Queen.prototype.pop = function () {
	while(!this.stack1.isEmpty()) {
		this.stack2.push(this.stack1.pop())
	}
	return this.stack2.pop()
}
const queen = new Queen(1,2,3)
queen.push(4,5,6)
console.log(queen.pop())
console.log(queen.pop())
console.log(queen.pop())


实现一个栈,使其入栈push,出栈pop,获取栈的最小元素min的时间复杂度均为O(1)

console.log(`--------------- MinStack 实现一个栈,使其入栈push,出栈pop,获取栈的最小元素min的时间复杂度均为O(1)  -----------------`)
// 每次元素入栈的时候,将最小值存入minData,这样的话最小值总是minData的栈顶元素
function MinStack() {
	Stack.call(this)
	this.minData = new Stack()
}
MinStack.prototype = Object.create(Stack.prototype)
MinStack.prototype.constructor = MinStack
MinStack.prototype.push = function (data) {
	if(this.minData.isEmpty()) this.minData.push(data)
	else {
		this.minData.peak() < data ? this.minData.push(this.minData.peak()) : this.minData.push(data)
	}
	return Stack.prototype.push.call(this, data)
}
MinStack.prototype.getMinData = function () {
	return this.minData.peak()
}
MinStack.prototype.pop = function () {
	this.minData.pop()
	return Stack.prototype.pop.call(this)
}
const stack2 = new MinStack()
stack2.push(2)
stack2.push(4)
console.log(stack2.getMinData())
stack2.push(1)
stack2.push(0)
console.log(stack2.getMinData())
stack2.pop()
console.log(stack2.getMinData())


判断是否是回文字符串

console.log(`--------------- 判断是否是回文 -----------------`)
// 用一个栈保存字符串,出栈顺序构成的字符串和原字符串相等
function isPalindrome(str) {
	if(!str) return false
	const stack = new Stack(...Array.from(str))
	let result = ''
	while(!stack.isEmpty()) {
		result += stack.pop()
	}
	return result === str
}
console.log(isPalindrome('abcdcba'))
console.log(isPalindrome('abcd4cba'))