1. 数据结构——栈
栈是一种特殊的线性表,仅能在栈顶进行操作,有着后进先出的特性,例如我们现实生活中的羽毛球桶和糖葫芦,最后放入的先拿出。
栈的方法
将元素添加进栈中被成为入栈(压栈)的方法push
将当前栈顶元素删除称为出栈的方法 pop
查看当前栈顶元素的方法 peek
查看当前栈的长度方法 size
删除栈的方法 clear
栈中的属性是top用来记录当前栈顶的位置
代码实现如下:
function Stack(){
this.itemArr=[];
this.top=0;//初始化栈顶位置为0
}
Stack.prototype={
push:function(el){
return this.itemArr[this.top++]=el;
},
pop:function(){
return this.itemArr.splice(--this.top,1)
},
peek:function(){
return this.itemArr[this.top-1];
},
size:function(){
return this.top;
},
clear:function(){
this.top=0;
this.itemArr=[];
return this.itemArr;
}
}
var arr=new Stack();
小试几道练习题:
1、下面的字符串中包含小括号,请编写一个函数判断字符串中的括号是否合法,合法,意味着括号成对出现 实现如下:
function is_leagl_brackets(string){
var stack = new Stack()
for(var i;i<string.length;i++){
var item = string[i]
// 如果是左括号,就入栈
if(item === "("){
stack.push()
}else if(item === ")"){
// 如果遇到右括号,判断栈是否为空,为空不合法
if(stack.isEmpty()){
return false
}else{
// 不为空就删除左括号
stack.pop()
}
}
}
// 如果栈为空,说明字符串合法
return stack.isEmpty()
}
console.log('ss(hh)(jjj(hhghj)')
2、计算逆波兰表达式(即后缀表达式) 请编写函数calc(exp)实现后缀表达式,exp的类型是数组 实现如下:
function calc(exp){
var stack = new Stack()
for(var i;i<exp.length;i++){
var item = exp[i]
if(['+','-','*','/'].indexOf(item)>=0){
// 弹出两个栈顶元素,第一次弹出的放在运算符的右边,第二次弹出的放在左边
var value1 = stack.pop() //5
var value2 = stack.pop() //13
var exp_str = value1+item+value2
// 计算并取整,将计算结果压入栈中
var res = parseInt(eval(exp_str))
stack.push(res.toString())
}else{
stack.push(item)
}
}
// 最终返回栈顶元素,即是计算结果
return stack.pop()
}
console.log(calc(['4','13','5','/','+'])) // 6
3、实现一个min方法的栈,返回栈里最小的元素,时间复杂度为O(1) 实现如下:
function minStack(exp){
// 定义两个栈
dataStack = new Stack()
minStack = new Stack()
// 入栈方法
this.push = function(item){
dataStack.push(item)
if(minStack.isEmpty()&&item<dataStack.pop()){
minStack.push(item)
}else{
// 如果item⼤于等于栈顶元素,把min_stack的栈顶元素再放⼊⼀次
// min_stack的元素个数要和data_stack 保持⼀致
minStack.push(minStack.top())
}
}
// 出栈
this.pop = function(item){
dataStack.pop()
minStack.pop()
}
//返回最小值
this.min = function(){
return minStack.top()
}
}
minStack = new minStack()
minstack.push(3);
minstack.push(6);
minstack.push(8);
console.log(minstack.min());
minstack.push(2);
console.log(minstack.min());
minstack.pop();
console.log(minstack.min());
4、使用栈,完成中序表达式转后序表达式 例如:['4','+','8'] 转为 ['4','8','+'] 实现如下:
// 定义运算符得优先级
var priority_map = {
"+":1,
"-":1,
"/":2,
"*":2
}
function infix(exp){
var stack = new Stack()
var infixList = []
for(var i;i<exp.length;i++){
var item = exp[i]
// 判断是数字,直接放入到infixList
if(isNaN(item)){
infixList.push(item)
}else if(item === '('){
// 左括号入栈
stack.push(item)
}else if(item === ')'){
// 遇到右括号,把栈顶元素弹出,直到遇到左括号
while(stack.top!= '('){
infixList.push(stack.pop())
}
// 左括号出栈
stack.pop()
}else{
// 遇到运算符,把栈顶的运算符弹出,直到栈顶的运算符优先级小于当前运算符
while(!stack.isEmpty() && ['+','-','*','/'].indexOf(stack.top())>=0 && priority_map[stack.top()]>=priority_map[item]){
infixList.push(stack.pop())
}
// 当前运算符入栈
stack.push(item)
}
}
// for循环结束后,栈里可能还有元素,都弹出放在postfix_list中
while(!stack.isEmpty()){
infixList.push(stack.pop())
}
return infixList
}
console.log(infix(['(','1','-','+','9',')']))
以上为本小白学习算法的梦想之路的开端,欢迎大家指正交流,共勉!!!