JS 数据结构,栈(Stack)

前言 :


在说栈之前先来说一下我们比较熟悉的 数组,JS 中已经对数组做了很好的封装,可以通过一些 API 方法实现指定位置插入,指定元素删除,还实现了自动扩容的功能等。在其他的语言中,如 JAVA。数组作为底层数据结构,存在无法自动扩容等问题,在 ArrayList 等中,会使用新建更大的数组去替换原数组的方式去实现。总而言之,从数据结构来说,数组的插入和删除操作很耗性能,比较复杂的,因为要考虑到其他元素下标值得改变。但是数组又有它自己独特得优势,可以通过下标查找指定元素(高效)后续链表得出现,弥补了数组插入和删除,不自动扩容等操作。但是它不利于查找(线性查找,低效)。


  • 栈的概念 ?

我们知道 数组是一种线性结构,并且可以在数组的任意位置插入和删除数据,有时候,我们为了实现某些功能,必须对这种任意性加以限制。栈和队列就是比较常见的受限的线性结构。

  • 栈的特点 ?

栈有底部(栈底),底部封闭,只能在顶部(栈顶)添加或者删除元素。其中添加元素称为进栈,删除元素称为出栈。它具有是 后进先出(LIFO)的特性。

  • 栈的使用场景举例  ?
  1. 函数调用栈 : A 函数调用了 B 函数,B 函数调用了 C 函数, C 函数又调用了 D 函数。栈结构(A-B-C-D),A 函数处于栈底,D 函数处于栈顶,当栈顶的函数执行完成之后,会弹出(出栈),所以函数执行完成顺序为:D-C-B-A。
  2. 在闭包中:会出现栈溢出的问题。因为闭包是都函数自身的调用,是不会被弹出栈的。
  • 一道栈的面试题 ?

面试题 : 有六个元素 6,5,4,3,2,1 的顺序进栈(并不是一次性的进栈,而是进栈期间伴随着出栈),下面哪一个出栈序列不合法 ?

        A:5,4,3,6,1,2

        B:4,5,3,2,1,6

        C :  3,4,6,5,2,1

        D :2,3,4,1,5,6

解析:答案为 C ,当 3 出栈的时候,(6,5,4,3)已经确保在栈中。当 3 和 4 满足后,6 出栈,是不可能的,因为之前栈顶元素已经确定为 5,应该先弹出 5。 

  • 栈的实现 ?

实现栈结构,可以通过 数组实现,也可以通过 链表实现。下面去演示用数组去实现的过程。(JS

// 封装栈类
function Stack(){
    // 栈中的元素
    this.items = [];
    // 栈中的操作
    //1,进栈操作
    Stack.prorotype.push = function(el){
        this.items.push(el);
    }
    //2,出栈操作,返回移除的栈顶元素
    Stack.prototype.pop = function(){
        return this.items.pop();
    }
    //3,返回栈顶元素,不对栈做任何修改
    Stack.prototype.peek = function(){
        return this.items[this.items.length - 1];
    }
    //4,判断栈是否为空
    Stack.prototype.isEmpty = function(){
        return this.items.length === 0;
    }
    //5,返回栈里面的元素个数
    Stack.prototype.size = function(){
        return this.items.length;
    }
    //6,将栈结构内容以字符串形式返回
    Stack.prototype.toString = function(){
        var resultStr = '';
        for(var i=0; i<this.items.length; i++){
            resultStr += this.items[i] + '';
        }
        return resultStr;
    }
}

// 栈的使用 
var s = new Stack();
stack.push(10);
stack.push(34);
stack.push(56);
stack.push(78);
alert(stack);
stack.pop();
alert(stack);
alert(stack.peek());
alert(stack.isEmpty());
alert(stack.size());
alert(stack.toString());
  • 栈的使用实例——十进制转换为二进制 ?
// 封装栈类
function Stack(){
    //栈中的元素
	this.items = [];
    //栈中的方法
    //1,元素进栈
	Stack.prototype.push = function(el){
		this.items.push(el);
	}
    //2,元素出栈
    Stack.prototype.pop = function(){
		return this.items.pop();
	}
    //3,查看栈顶元素
	Stack.prototype.peek = function(){
		return this.items[this.items.length -1];
   	}
    //4,判断栈是否为空
	Stack.prototype.isEmpty = function(){
		return this.items.length === 0;
	}
    //5,返回栈里元素的个数
	Stack.prototype.size = function(){
		return this.items.length;
	}
    //6,将栈结构内容以字符串形式返回
	Stack.prototype.toString = function(){
		var resultStr = '';
		for(var i=0; i<this.items.length; i++){
			resultStr += this.items[i] + '';
		}
		return resultStr;
	}
}
	
// 转换函数			
function convert(num){
    // 使用栈
	var s = new Stack();
    // 当num小于等于0的时候终止循环
	while(num > 0){
    // 把每次num%2的结果压入栈中
		s.push(num%2);
    // 每次num更新数值为,num/2d的整数
		num = Math.floor(num/2);
	}
	var result = '';
	while(!s.isEmpty()){
		result += s.pop();
	}
	return result;
}

console.log(convert(10)); //1010			

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值