用js实现栈结构

本文详细讲解了数据结构中的栈和数组在JavaScript中的应用,包括栈的原理、操作(如push、pop、peek等)、栈在函数调用和递归中的角色,以及如何使用数组实现栈并进行基础操作。通过实际例子演示了将十进制转为二进制的过程。
摘要由CSDN通过智能技术生成

数据结构和算法(js版)
1.1.什么是数据结构?
数据结构就是在计算机中,存储和组织数据的方式。

例如:图书管理,怎样摆放图书才能既能放很多书,也方便取?

主要需要考虑两个问题:

操作一:新书怎么插入?
操作二:怎么找到某本指定的书?
常见的数据结构

数组(Aarray)
栈(Stack)
链表(Linked List)
图(Graph)
散列表(Hash)
队列(Queue)
树(Tree)
堆(Heap)
注意:数据结构与算法与语言无关,常见的编程语言都有直接或间接的使用上述常见的数据结构。

1.2.什么是算法?
算法(Algorithm)的定义

一个有限指令集,每条指令的描述不依赖于语言; 接收一些输入(有些情况下不需要输入); 产生输入; 一定在有限步骤之后终止; 算法(Algorithm)通俗理解:解决问题的办法/步骤逻辑。数据结构的实现,离不开算法

1.js数组可以存放不同的数据类型,常见语言的数组不能存放不同的数据类型,因此所有再封装时通常存放再数组中的是Object类型

2.常见语言的数组容量不会自动改变(需要进行扩容操作),js底层可以自动扩容

3.常见语言的数组进行中间插入和删除操作性能比较低,修改和查找下标某个元素效率比较高

2.栈结构
​ 数组是一个线性结构,并且可以再数组的任意位置插入和删除元素,而栈和队列就是比较常见的受限的线性结构

栈是一种受限的线性表,后进先出(LIFO)

​ 其限制是仅允许在表的一端进行插入和删除运算,这一端被称为栈顶,相对的另一端被称为栈底。

​ LIFO(last in first out)表示就是后进入的元素,第一个弹出栈空间,类似于自动餐托盘,最后放上去的,往往先拿出去使用

​ 向一个栈中插入新元素又称作进栈,入栈或压栈 ,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;

​ 从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素,成为新的栈顶元素

image-20200226131817102

栈的特点是:先进后出,后进先出

程序中的栈结构:

函数调用栈:A(B(C(D()))):即A函数中调用B,B调用C,C调用D;在A执行的过程中会将A压入栈,随后B执行时B也被压入栈,函数C和D执行时也会被压入栈。所以当前栈的顺序为:A->B->C->D(栈顶);函数D执行完之后,会弹出栈被释放,弹出栈的顺序为D->C->B->A;
递归:为什么没有停止条件的递归会造成栈溢出?比如函数A为递归函数,不断地调用自己(因为函数还没有执行完,不会把函数弹出栈),不停地把相同的函数A压入栈,最后造成栈溢出(Stack Overfloat)
3.练习:题目:有6个元素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 (√) 题目所说的按顺序进栈指的不是一次性全部进栈,而是有进有出,进栈顺序为6 -> 5 -> 4 -> 3 -> 2 -> 1。

解析:

A答案:65进栈,5出栈,4进栈出栈,3进栈出栈,6出栈,21进栈,1出栈,2出栈(整体入栈顺序符合654321); B答案:654进栈,4出栈,5出栈,3进栈出栈,2进栈出栈,1进栈出栈,6出栈(整体的入栈顺序符合654321); C答案:6543进栈,3出栈,4出栈,之后应该5出栈而不是6,所以错误; D答案:65432进栈,2出栈,3出栈,4出栈,1进栈出栈,5出栈,6出栈。符合入栈顺序;

栈的常见操作:

​ push():添加一个新元素到栈顶位置;

​ pop(): 移除栈顶的元素,同时返回被移除的元素

​ peek():返回栈顶的元素,不对栈做任何修改(该方法,不会移除栈顶元素,仅仅返回它)

​ isEmpty() : 如果栈里面没有任何元素就返回true,否则就返回false

​ size() : 返回栈里的元素个数,这个方法和数组的length属性类似

​ toString() : 将栈结构的内容以字符串形式返回

实现栈结构有两种比较常见的方式:

​ 基于数组实现

​ 基于链表实现

封装栈(基于数组实现):

// Method:和某个对象实例有联系的,称为方法
        // function:
        // 栈封装类
        function Stack(){
            // 栈中的属性
            this.items = [];

            // 栈的相关操作
            // 1.将元素压入栈
        // this.push = function (){

        // }  //使每个实例都有一个方法,不推荐,占用内存
            Stack.prototype.push = function (element){
                this.items.push(element);
            } //放在原型上共享,推荐使用
            // 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.toString方法
            Stack.prototype.toString = function(){
                var resultString = ' ';
                for (var i=0;i<this.items.length;i++){
                    resultString += this.items[i] + ' ';
                }
                return resultString
            }
        }
        
   // 栈的使用
        var s = new Stack();
        s.push(20);
        s.push(100);
        s.push(1);
        console.log(s);
        console.log(s.peek());
        s.pop();
        console.log(s);
        console.log(s.isEmpty());
        console.log(s.size());

使用ES6的方式封装

      class Stack{
            constructor(){
                // 属性
                this.count = 0; //使用count 属性来帮助我们记录栈的大小(也帮助我们从数据结构中添加和删除元素)
                this.items = {};
            }
            // 方法
            // 往栈中添加元素
            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;
                while (!this.isEmpty()){
                    this.pop();
                }
            };
            // toString()方法
            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 decTobin(decNumber){
           // 1.定义一个栈对象
            var s = new Stack();
             // 2.循环数组大于0时
            while(decNumber / 2 >0){
            // 2.1获取余数,并且放入到栈中
                s.push(decNumber % 2);
                 // 2.2获取整除后的结果,作为下一次运行的数字
                decNumber = Math.floor(decNumber / 2)
            }
		 // 3.从栈中取出0和1,从上到下取
            var newString = '';
            while(!s.isEmpty()){
                newString +=s.pop();
            }
                return newString;
        }
 
        console.log(decTobin(10));
        console.log(decTobin(100));
        console.log(decTobin(1000));
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值