js算法入门学习系列1

100 阅读2分钟

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',')']))

以上为本小白学习算法的梦想之路的开端,欢迎大家指正交流,共勉!!!